This question already has answers here:
How can I upload files asynchronously with jQuery?
(34 answers)
Closed 6 years ago.
I can send a POST using curl:
curl -X POST -F 'secret=supersecretkey' --form file=#galleta.jpg http://127.0.0.1:5000/
But I donĀ“t know how to do the same using AJAX and jQuery.
Step 1: HTML AND Styling
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>HTML5 File API</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div id="main">
<h1>Upload Your Images</h1>
<form method="post" enctype="multipart/form-data" action="upload.php">
<input type="file" name="images" id="images" multiple />
<button type="submit" id="btn">Upload Files!</button>
</form>
<div id="response"></div>
<ul id="image-list">
</ul>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script src="upload.js"></script>
</body>
</html>
The CSS File
body {
font: 14px/1.5 helvetica-neue, helvetica, arial, san-serif;
padding:10px;
}
h1 {
margin-top:0;
}
#main {
width: 300px;
margin:auto;
background: #ececec;
padding: 20px;
border: 1px solid #ccc;
}
#image-list {
list-style:none;
margin:0;
padding:0;
}
#image-list li {
background: #fff;
border: 1px solid #ccc;
text-align:center;
padding:20px;
margin-bottom:19px;
}
#image-list li img {
width: 258px;
vertical-align: middle;
border:1px solid #474747;
}
Step 2 : The PHP - upload.php
<?php
foreach ($_FILES["images"]["error"] as $key => $error) {
if ($error == UPLOAD_ERR_OK) {
$name = $_FILES["images"]["name"][$key];
move_uploaded_file( $_FILES["images"]["tmp_name"][$key], "uploads/" . $_FILES['images']['name'][$key]);
}
}
echo "<h2>Successfully Uploaded Images</h2>";
Step 3 : Javascript
(function () {
var input = document.getElementById("images"),
formdata = false;
if (window.FormData) {
formdata = new FormData();
document.getElementById("btn").style.display = "none";
}
}();
function showUploadedItem (source) {
var list = document.getElementById("image-list"),
li = document.createElement("li"),
img = document.createElement("img");
img.src = source;
li.appendChild(img);
list.appendChild(li);
}
if (input.addEventListener) {
input.addEventListener("change", function (evt) {
var i = 0, len = this.files.length, img, reader, file;
document.getElementById("response").innerHTML = "Uploading . . ."
for ( ; i < len; i++ ) {
file = this.files[i];
if (!!file.type.match(/image.*/)) {
}
}
}, false);
}
if ( window.FileReader ) {
reader = new FileReader();
reader.onloadend = function (e) {
showUploadedItem(e.target.result);
};
reader.readAsDataURL(file);
}
if (formdata) {
formdata.append("images[]", file);
}
if (formdata) {
$.ajax({
url: "upload.php",
type: "POST",
data: formdata,
processData: false,
contentType: false,
success: function (res) {
document.getElementById("response").innerHTML = res;
}
});
}
Follow this tutorial explaining how to achieve this.
Related
I am trying to Upload an excel file at client side in AngularJS UI Grid using SheetJS. The code works fine in Chrome and Firefox, but on IE it gives the following error Object doesn't support property or method 'readAsBinaryString'
I tried various solution on stack overflow like using readAsBinaryArray or readAsText instead of using readAsBinaryString but I am unable to solve my problem.
I am sharing my code below it consists of 3 files: index.html, app.js and main.css
Code for index.html is as below
<!DOCTYPE html>
<html ng-app="app">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=11" />
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Expires" content="Sat, 01 Dec 2001 00:00:00 GMT">
<link data-require="bootstrap-css#*" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular.js"></script>
<script src="https://cdn.rawgit.com/SheetJS/js-xlsx/v0.8.0/dist/xlsx.full.min.js"></script>
<script src="https://cdn.rawgit.com/SheetJS/js-xlsx/v0.8.0/dist/ods.js"></script>
<script src="https://github.com/SheetJS/js-xlsx/blob/master/shim.js"></script>
<script src="http://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/release/3.0.0-rc.22/ui-grid.min.js"></script>
<link rel="stylesheet" href="http://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/release/3.0.0-rc.22/ui-grid.min.css" />
<link rel="stylesheet" href="css/main.css" type="text/css" />
</head>
<body>
<div ng-controller="MainCtrl as vm">
<div id="grid1" ui-grid="vm.gridOptions" class="grid">
<div class="grid-msg-overlay" ng-show="!vm.gridOptions.data.length">
<div class="msg">
<div class="center">
<span class="muted">Select Excel File</span>
<br />
<input ng-attr-type="{{'file'}}" accept=".xls,.xlsx,.csv" fileread="" opts="vm.gridOptions" multiple="false" />
</div>
</div>
</div>
</div>
<br />
<br />
<button type="button" class="btn btn-success" ng- click="vm.reset()">Reset Grid</button>
<span> </span>
<button type="button" class="btn btn-success" ng-click="">Save</button>
</div>
<script src="js/app.js"></script>
</body>
</html>
Code for app.js is as below
(function (angular) {
"use strict";
angular.module('app', ['ui.grid']).controller('MainCtrl', ['$scope', function ($scope) {
var vm = this;
vm.gridOptions = {};
vm.reset = reset;
function reset() {
vm.gridOptions.data = [];
vm.gridOptions.columnDefs = [];
}
}])
.directive("fileread", [function () {
return {
scope: {
opts: '='
},
link: function ($scope, $elm, $attrs) {
$elm.on('change', function (changeEvent) {
var reader = new FileReader();
reader.onload = function (evt) {
$scope.$apply(function () {
var data = evt.target.result;
var workbook = XLSX.read(data, {type: 'binary'});
var headerNames = XLSX.utils.sheet_to_json( workbook.Sheets[workbook.SheetNames[0]], { header: 1 })[0];
var data = XLSX.utils.sheet_to_json( workbook.Sheets[workbook.SheetNames[0]]);
$scope.opts.columnDefs = [];
headerNames.forEach(function (h) {
$scope.opts.columnDefs.push({ field: h });
});
$scope.opts.data = data;
$elm.val(null);
});
};
reader.readAsBinaryString(changeEvent.target.files[0]);
});
}
}
}]);
Code for main.css
body {
padding: 20px;
}
.grid {
width: 100%;
height: 250px;
}
.grid-msg-overlay {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
background: rgba(0, 0, 0, 0.4);
}
.grid-msg-overlay .msg {
opacity: 1;
position: absolute;
top: 20%;
left: 20%;
width: 60%;
height: 50%;
background-color: #eee;
border-radius: 4px;
border: 1px solid #555;
text-align: center;
font-size: 24px;
display: table;
}
.grid-msg-overlay .msg > .center {
display: table-cell;
vertical-align: middle;
}
.grid input[type="file"] {
font-size: 14px;
display: inline-block;
}
Please can someone help me to understand how can I resolve this issue
IE does not implement the FileReader readAsBinaryString() method. However, as per the SheetJS documentation, you can test for support, and fallback to readAsArrayBuffer() instead.
var readAsBinary = "readAsBinaryString" in FileReader;
if (readAsBinary) {
reader.readAsBinaryString(changeEvent.target.files[0]);
} else {
reader.readAsArrayBuffer(changeEvent.target.files[0]);
}
Then in the unload method you have to handle the result as follows:
var workbook;
if (readAsBinary) {
workbook = XLSX.read(data, {type: 'binary'});
} else {
function fixdata(data) {
var o = "", l = 0, w = 10240;
for(; l<data.byteLength/w; ++l) o+=String.fromCharCode.apply(null,new Uint8Array(data.slice(l*w,l*w+w)));
o+=String.fromCharCode.apply(null, new Uint8Array(data.slice(l*w)));
return o;
}
workbook = XLSX.read(btoa(fixdata(data)), {type: 'base64'});
}
I am new to this.All i am trying to do is upload a image and send it to server to insert in a database.As a start i am limited to echoing the file name which i will send.But i kept on failing to do so.Getting some noisy or undesirable output which makes no sence.Can't figure out the mistakes in this code.It would be great if someone help me with this problem.Thanks!
html and ajax:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>file upload</title>
<!-- Make sure the path to CKEditor is correct. -->
<style>
#mydiv{
position: relative;
overflow: hidden;
width:80px;
height:30px;
background:crimson;
color:white;
text-align:center;
padding:auto;
border-radius:4px ;
border:1px solid black;
font-size:22px;
}
#files{
position: absolute;
top: 0;
right: 0;
margin: 0;
padding: 0;
font-size: 20px;
cursor: pointer;
opacity: 0;
filter: alpha(opacity=0);
}
</style>
</head>
<body>
<form action='file.php' id='myform' method='POST' enctype='multipart/form-data' style='width:80px;height:70px;border:2px solid skyblue;'>
<div id='mydiv'>upload
<input type="file" id="files" name="files" multiple />
</div>
<span id='txtHint'></span>
</form>
<output id="list"></output>
<script>
function handleFileSelect(evt) {
var files = evt.target.files;
var formData = new FormData();
for (var i = 0, f; f = files[i]; i++) {
if (!f.type.match('image.*')) {
continue;
}
formData.append('image_name',f,f.name);
var name =f.name;
console.log(name);
if (name='') {
document.getElementById("txtHint").innerHTML ='fill the name field';
return;
} else {
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("txtHint").innerHTML = xmlhttp.responseText;
}
}
xmlhttp.open("POST", "file2.php", true)
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
xmlhttp.send(formData);
}
}
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>
</body>
</html>
php file:
echo $_FILES['image_name'];
To retrieve the upload file name just do:
echo $_FILES['image_name']['name']
EDIT : According to the name of your html input
echo $_FILES['files']['name']
What about to use BlueImp ? BlueImp is the best i think, and you can easily include on your projects
https://github.com/blueimp/jQuery-File-Upload
here's my html with javascript using webcam.js. I just followed the https://github.com/jhuckaby/webcamjs on how you will implement it using existing form.
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>WebcamJS Test Page</title>
<style type="text/css">
body { font-family: Helvetica, sans-serif; }
h2, h3 { margin-top:0; }
form { margin-top: 15px; }
form > input { margin-right: 15px; }
#results { float:right; margin:20px; padding:20px; border:1px solid; background:#ccc; }
</style>
</head>
<body>
<div id="results">Your captured image will appear here...</div>
<h1>WebcamJS Test Page</h1>
<h3>Demonstrates simple 320x240 capture & display</h3>
<div id="my_camera"></div>
<!-- First, include the Webcam.js JavaScript Library -->
<script type="text/javascript" src="../webcam.js"></script>
<!-- Configure a few settings and attach camera -->
<script language="JavaScript">
Webcam.set({
width: 320,
height: 240,
image_format: 'jpeg',
jpeg_quality: 90
});
Webcam.attach( '#my_camera' );
Webcam.snap( function(data_uri) {
var raw_image_data = data_uri.replace(/^data\:image\/\w+\;base64\,/, '');
document.getElementById('mydata').value = raw_image_data;
document.getElementById('myform').submit();
} );
</script>
<!-- A button for taking snaps -->
<form id="myform" method="post" action="myscript.php">
<input id="mydata" type="hidden" name="mydata" value=""/>
<input type=button value="Take Snapshot" onClick="take_snapshot()">
<input type="submit" value="submit">
</form>
<!-- Code to handle taking the snapshot and displaying it locally -->
<script language="JavaScript">
function take_snapshot() {
// take snapshot and get image data
Webcam.snap( function(data_uri) {
// display results in page
document.getElementById('results').innerHTML =
'<h2>Here is your image:</h2>' +
'<img src="'+data_uri+'"/>';
} );
}
</script>
here's the myscript.php to save the image. I successfully save the PATH in the database but I'm getting a corrupted .jpg file (file size always in 7 bytes).
<?php
include 'connect.php';
$encoded_data = $_POST['mydata']; // to get the base 64 code image link
$name = base64_decode($encoded_data); // to convert base 64 code
$name = date('YmdHis');
$newname="images/".$name.".jpg";
$file = file_put_contents( $newname, file_get_contents('php://input') );
if (!$file) {
print "Error occured here";
exit();
}
else
{
$sql="INSERT INTO image (images) VALUES('$newname')";
$result=mysqli_query($con,$sql);
$value=mysqli_insert_id($con);
$_SESSION["myvalue"]=$value;
}
$url = 'http://' . $_SERVER['HTTP_HOST'] . dirname($_SERVER['REQUEST_URI']) . '/' . $newname;
print "$url\n";
?>
After all the trail and errors i found out you'll need to convert the base64 string to a blob and then attach to a file before sending.
var binaryImg = atob(base64string);
var length = binaryImg.length;
var ab = new ArrayBuffer(length);
var ua = new Uint8Array(ab);
for (var i = 0; i < length; i++) {
ua[i] = binaryImg.charCodeAt(i);
}
var blob = new Blob([ab], {
type: "image/jpeg"
});enter code here
var imgFile = new File([blob], 'photo.jpeg', {type: 'image/jpeg'});
Now you can use the imgFile to send across to a remote server.
When the page is loaded, the image specified in src is displayed.When a user clicks on the form to upload the image,everything works fine except the image on the page does not change.
It is because when the user clicks on the form to upload the image, he is directed to php file 2 but from there there is no request to change the image in php file 1. How can I achieve this (using ajax and jquery)?
Try this code. This is the core.
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('#imgInp').on('change', function() {
readPath(this);
});
});
function readPath(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#blah').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
</script>
</head>
<body>
<form id="form1">
<input type='file' id="imgInp" />
<img id="blah" src="#" width="500px" height="200px" alt="your image" />
</form>
</body>
</html>
Here is another code snippet. Check your conditions in the server part and don't forget provide the locations correctly in server side and image src.
HTML Part
<!doctype html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.js"></script>
<script src="http://malsup.github.com/jquery.form.js"></script>
<style>
form { display: block; margin: 20px auto; background: #eee; border-radius: 10px; padding: 15px }
#progress { position:relative; width:400px; border: 1px solid #ddd; padding: 1px; border-radius: 3px; }
#bar { background-color: #B4F5B4; width:0%; height:20px; border-radius: 3px; }
#percent { position:absolute; display:inline-block; top:3px; left:48%; }
</style>
</head>
<body>
<h1>Ajax File Upload Demo</h1>
<img id="blah" src="#" width="500px" height="200px" alt="your image" />
<form id="myForm" action="upload.php" method="post" enctype="multipart/form-data">
<input type="file" size="60" name="myfile">
<input type="submit" value="Ajax File Upload">
</form>
<div id="progress">
<div id="bar"></div>
<div id="percent">0%</div >
</div>
<br/>
<div id="message"></div>
<script>
$(document).ready(function()
{
var options = {
beforeSend: function()
{
$("#progress").show();
//clear everything
$("#bar").width('0%');
$("#message").html("");
$("#percent").html("0%");
},
uploadProgress: function(event, position, total, percentComplete)
{
$("#bar").width(percentComplete+'%');
$("#percent").html(percentComplete+'%');
},
success: function()
{
$("#bar").width('100%');
$("#percent").html('100%');
},
complete: function(response)
{
$("#blah").attr("src",response.responseText);
},
error: function()
{
$("#message").html("<font color='red'> ERROR: unable to upload files</font>");
}
};
$("#myForm").ajaxForm(options);
});
</script>
</body>
</html>
Upload.php
<?php
//upload.php
$output_dir = "C:/wamp/www/";
if(isset($_FILES["myfile"]))
{
//Filter the file types , if you want.
if ($_FILES["myfile"]["error"] > 0)
{
echo "Error: " . $_FILES["file"]["error"] . "<br>";
}
else
{
//move the uploaded file to uploads folder;
move_uploaded_file($_FILES["myfile"]["tmp_name"],$output_dir. $_FILES["myfile"]["name"]);
echo $_FILES["myfile"]["name"];
}
}
?>
I have a form in which users can submit issues, what I want to happen is when users hit the add button, i want what they add to be posted in the box below. So say the add something, x out the window and come back to add something else later what they added previously will still be there.
here is my fiddle
http://jsfiddle.net/grahamwalsh/rCB9V/
IssueList(html)
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Issue List</title>
<script src="Scripts/jquery-2.1.1.js"></script>
<script src="Scripts/knockout-3.1.0.js"></script>
<script src="Issuelist.js"></script>
<link type="text/css" rel="stylesheet" href="Issuelistcss.css" />
</head>
<body>
<div class='issuelist'>
<form data-bind="submit:addIssue">
Add Issue: <input type="text" data-bind='value:issueToAdd, valueUpdate: "afterkeydown"' />
<button type="submit" data-bind="enable: issueToAdd().length > 0">Add</button>
</form>
<p>Your Issues:</p>
<select multiple="multiple" data-bind="options:allIssues, selectedOptions:selectedIssues"> </select>
<div>
<button data-bind="click: removeSelected, enable: selectedIssues().length > 0">Remove</button>
<button data-bind="click: sortIssues, enable: allIssues().length > 1">Sort</button>
</div>
</div>
</body>
</html>
IssueList (js)
$(document).ready(function(){
var Issuelist = function () {
this.issueToAdd = ko.observable("");
this.allIssues = ko.observableArray(["test"]);
this.selectedIssues = ko.observableArray(["test"]);
this.addIssue = function () {
if ((this.issueToAdd() != "") && (this.allIssues.indexOf(this.issueToAdd()) < 0))
this.allIssues.push(this.issueToAdd());
this.issueToAdd("");
};
this.removeSelected = function () {
this.allIssues.removeAll(this.selectedIssues());
this.selectedIssues([]);
};
this.sortIssues = function () {
this.allIssues.sort();
};
};
ko.applyBindings(new Issuelist());
});
IssueListcss
body { font-family: arial; font-size: 14px; }
.issuelist { padding: 1em; background-color: #87CEEB; border: 1px solid #CCC; max-width: 655px; }
.issuelist input { font-family: Arial; }
.issuelist b { font-weight: bold; }
.issuelist p { margin-top: 0.9em; margin-bottom: 0.9em; }
.issuelist select[multiple] { width: 100%; height: 8em; }
.issuelist h2 { margin-top: 0.4em; }
You could have the form 'post' to its self then make an ajax request for their new issue and put it inside a div. I would also hold off on so much on the javascript or have support for those without it:
getissues.php
getissues.php
<?php
/*
connect to your database code
*/
$query = "select * from issues";
$result = mysql_query($query, $connect);
while($row = mysql_fetch_array($result))
{
echo $row['issues'];
echo '<hr>';
}
?>
process.php
process.php:
<?php
/*
connect to your database
*/
$issue = strip_tags$_POST['issue'];
$query = "insert into issues (issue) values ('$issue')";
$result = mysql_query($query, $connect);
?>
main form page:
<!DOCTYPE HTML>
<html>
<head>
<title>issue page</title>
<script src="Scripts/jquery-2.1.1.js"></script>
<script src="Scripts/knockout-3.1.0.js"></script>
<script src="Issuelist.js"></script>
<link type="text/css" rel="stylesheet" href="Issuelistcss.css" />
<script type="text/javascript">
function check()
{
var request = $.ajax({
url: "getissues.php",
type: "POST",
dataType: "html"
});
request.done(function(msg) {
$("#issues").html(msg);
});
request.fail(function(jqXHR, textStatus) {
alert( "Request failed: " + textStatus );
});
}
function validate()
{
var issue = $("#issue");
var errcount = 0;
if (issue == "")
{
errcount++;
alert("enter something");
}
if (errcount == 0)
{
/*
make request to php script to put issue into database
*/
$.post("process.php",
{
issue:issue
},
function(data,status){
window.alert("Request done!");
check();
});
}
}
</script>
</head>
<body>
<form action="issuelist.html" method="post">
Add Issue: <input type="text" name="issue"/>
Add Issue: <input type="text" name="issue" id="issue"/>
<button onclick="validate()">submit</button>
</form>
<div id="issues" class="issues">
<!--your ajax fetched issues will appear here-->
</div>
</body>
</html>
hope this helps!