how to view image on mvc website instantly after uploading? - html

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

Related

How can I create a button or link that automatically downloads a file based on a URL?

Here's a website: Download link generator
And here's the form in the page source:
<form id="download" class="download_action" method="POST">
<input type="hidden" name="action" value="download_action">
<label for="url">Please enter the URL you would like to save as a file:</label>
<div class="field">
<input id="url" class="text mr-3" name="keyword" type="text">
<input class="submit" title="Save target as" type="submit" value="Save target as">
</div>
<div class="tool-target" style="padding-bottom: 10px;"> </div>
<div id="return"> </div>
<input type="hidden" id="_wpnonce" name="_wpnonce" value="5c9a47c6d6" /><input type="hidden" name="_wp_http_referer" value="/tools/download-link-generator" />
</form>
It seems to be a server-side solution, but I don't have much information about servers and how they do it. I wonder how it works exactly. Can similar projects be built for free, or do I need paid hosting and a server plus a vast knowledge of running it? What I finally want is a link/button that will force download.
Evidently I was wrong. pythonanywhere is really easy.
(But you must use any paid plan in order to access most outside servers (i.e. get files from any website you want)). As of right now, the cheapest plan they have is $5 a month.
Stackoverflow isn't a code-writing service.
But enjoy this little exception.
here's a basic implementation of what you've asked for:
We're gonna use an HTTP server written in Python, using a framework called Flask.
That server will provide two functions:
Serve us that basic form you've described
allow us to request from the backend the file we want, and it will force our web browser to download it (and not display it, for example)
Step 1
Create a "pythonanywhere" account.
Attention: your website will be hosted on username.pythonanywhere.com, choose wisely.
hit "open web tab"*
Step 2
Select the latest Flask version in "add new web app" (3.10 in this case) and hit Next.
Step 3
verify the website works, click on that link, you should see "Hello from Flask!".
Step 4
Go to the "Files" tab, enter the mysite directory
and create a new directory called "templates"
Step 5
Create a new file called index.html,
and put this html in it:
(css and form taken from w3schools)
<!DOCTYPE html>
<html>
<style>
input[type=text], select {
width: 100%;
padding: 12px 20px;
margin: 8px 0;
display: inline-block;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
input[type=submit] {
width: 100%;
background-color: #4CAF50;
color: white;
padding: 14px 20px;
margin: 8px 0;
border: none;
border-radius: 4px;
cursor: pointer;
}
input[type=submit]:hover {
background-color: #45a049;
}
div {
border-radius: 5px;
background-color: #f2f2f2;
padding: 20px;
}
</style>
<body>
<h3>File Proxy</h3>
<div>
<form method="POST" action="/download"> <!-- notice the #app.route("/download"...) in the flask file -->
<label for="fpath">File Path</label>
<input type="text" id="fpath" name="fpath" placeholder="Path...">
<input type="submit" value="Submit">
</form>
</div>
</body>
</html>
Hit save
Step 6
Go back to the "Files" tab, and enter mysite directory again.
edit the flask_app.py file
and replace the code in it with the following:
from flask import Flask, request, render_template, Response
import requests
app = Flask(__name__)
content_type_to_extension={"text/html": ".html"}
FALLBACK_EXTENSION=".bin"
# get the path from the form, GET it ourselves, and return it with a content-type that will force the client's browser to download it and not attempt to display it.
#app.route("/download", methods=["POST"])
def loadData():
data = request.form["fpath"]
r = requests.get(data)
response = Response(
r.content,
status=r.status_code,
content_type="application/stream"
# content_type=r.headers['content-type']
)
# basic naming attempt. if it has a uri (text after the last /), let's (maybe falsly, this is a POC) assume that it has a file extension. (you can add regex tests and whatnot)
try:
fname = data.replace('://','')
fname = fname[fname.rindex("/")+1:]
assert (len(fname) > 1)
except (IndexError, ValueError, AssertionError):
fname = data.replace("/", "-")
ext = content_type_to_extension.get(r.headers['content-type'].split(";")[0], FALLBACK_EXTENSION) # if we can't find ther correct extension, fallback to .bin
fname += ext
response.headers["Content-Disposition"] = f'attachment; filename={fname}'
return response
#app.route("/")
def index():
return render_template("index.html") # that html file in /templates
if __name__ == "__main__":
app.run(host='0.0.0.0')
Hit save
Step 7
Go back to the "web" tab, and hit that green "reload" button. (or the blue reload icon next to the save in the flask_app.py edit panel)
And go to your website.
The requests library requires a schema to be specified.
so don't forget the http(s):// or add it via python.
If you don't have a paid account, checking out the error logs in the "web" tab tells us
OSError('Tunnel connection failed: 403 Forbidden')))
**NO MATCH**
or
Network is unreachable
So you gotta go with a paid plan.
Or find some other method to host your web server.
For the record - what we're doing here is creating a "dumbed-down" web gui version of a cli http client, like wget or curl.
you could just run in bash / powershell wget <your-url> and it would be basically the same.
This code can work, if you want to download a website on the same domain.
For example, you can download https://example.com/main.html , if your domain is https://example.com/
However, if your domain is https://example2.org/, it is not working.
The reason why you can not download all pages from the internet is the browser is using CORB for safety reason.
<head>
<script src="https://requirejs.org/docs/release/2.3.5/minified/require.js"></script>
</head>
<button type="button" id="down">Download</button>
<input id="InputURL" placeholder="The URL you want to download." style="width:100%">
<p id="HiddenLable" style="">
The HTML
</p>
<script language="javascript">
document.getElementById('down').onclick = function () {
//var filename = "Download.html";
//var content = "Hello, you download a text file by Javasctipt.";
//veiwweb(document.getElementById('InputURL').value);
//var content = document.getElementById("HiddenLable").innerHTML;
//console.log(content);
//download("DownLoad.html", content);
veiwweb(document.getElementById('InputURL').value);
};
function veiwweb(TheLink){
if ( window.ActiveXObject ) // windows
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
else if ( window.XMLHttpRequest ) // other sys
xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = Callback;
xmlHttp.open("GET", TheLink, false ); // read
xmlHttp.send(null);
}
function Callback()
{
if ( xmlHttp.readyState == 4 ) {
if ( xmlHttp.status == 200 ) {
var value = xmlHttp.responseText;
document.getElementById("HiddenLable").innerHTML = value;
download("DownLoad.html", value);
}
}
}
function download(filename, content) {
//can not use this function to call viewweb() function because the value may not downloaded yet.
var blob = new Blob([content], {type: 'text/plain'});
var url = window.URL.createObjectURL(blob);
var a = document.createElement('a');
a.style = "display: none";
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
setTimeout(function () {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 5);
}
</script>
If you tried to download a HTML from a different domain, you can see this in the console:
Access to XMLHttpRequest at 'https://******/' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
function downloadUrl(filename, text) {
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
If you have anchor element with url, you may fire element.click() through code.
var element = document.createElement('#your-achnor-tag-id'); //
element.click()

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>

Display image upload after page refresh

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 + "'>";
}
}

ASP.NET CORE reading a simple text file with user selection offline mode

I have made a MVC ASP.NET CORE 1.0 Webapp.
It will be used as offline app, i.e: server will be localhost always.
All I want to do is let the user click on a button called "browse" on the html page. and then a filepicker appears in front of them so they can just pick a file.
and then all I want to do is read that text file and do some logic with it later on.
I have tried Following
HTML
<form asp-action="Mark" asp-controller="Home" method="post" enctype="multipart/form-data">
<div class="form-group">
<label class="btn btn-primary" for="my-file-selector">
<input id="my-file-selector" type="file" name="file" style="display:none;" onchange="$('#upload-file-info').html($(this).val());">
Browse
</label>
<span class='label label-info' id="upload-file-info"></span>
</div>
<button type="submit" class="btn btn-default">Submit</button>
Controller Code
[HttpPost]
public IActionResult Mark(IFormFile file)
{
return View();
}
IMPORTANT :
the above code works fine to upload the file, but I dont want to upload any file as it takes too much time and unnecessary memory space, I only want to read the contents of the text file which user selected.
Thanks In Advance
You can do that by using FileReader in JavaScript.
Here is an example:
HTML:
<input type="file" id="file-input" />
JavaScript:
function readFile(e) {
var file = e.target.files[0];
if (!file) {
return;
}
var reader = new FileReader();
reader.onload = function(e) {
var contents = e.target.result; // here is your file content
};
reader.readAsText(file);
}
document.getElementById('file-input').addEventListener('change', readFile, false);
That will take care of reading file content on the client site but if you need to do that in the back end (controller) then you've to upload the file.

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"
);
}