POSTing data serverside AND execute javascript code on submitting a form - javascript

My goal is to upload some images to a server and provide them with a description.
On clicking an upload button, this is what I want to happen:
1) a javascript function dynamically adds a form to get a description
of the images.
2) on submitting the form:
a) the description entered in the form must be available $_POST['description'] at server side.
b) the images are sent to the server using an XMLHttpRequest
In the code I wrote the description is not available $_POST['description'].
When i remove the check if(!isset($_POST['description'])), the imagefiles are perfectly uploaded.
This is my code:
javascript code
upload.onclick = uploadPrompt;
// dynamically add a form
function uploadPrompt () {
// fileQueue is an array containing all images that need to be uploaded
if (fileQueue.length < 1) {
alert("There are no images available for uploading.");
} else {
var inputDescription = document.createElement("input");
inputDescription.className = "promptInput";
inputDescription.type = "text";
inputDescription.name = "description";
var inputButton = document.createElement("button");
inputButton.id = "promptInputButton";
inputButton.type = "submit";
inputButton.innerHTML = "Start uploading";
var promptForm = document.createElement("form");
promptForm.method = "post";
promptForm.action = "upload.php";
promptForm.onsubmit = uploadQueue;
promptForm.id = "promptForm";
promptForm.appendChild(inputDescription);
promptForm.appendChild(inputButton);
document.body.appendChild(promptForm);
}
}
function uploadQueue(ev) {
ev.preventDefault();
elementToBeRemoved = document.getElementById("promptForm");
elementToBeRemoved.parentElement.removeChild(elementToBeRemoved);
while (fileQueue.length > 0) {
var item = fileQueue.pop();
// item.file is the actual image data
uploadFile(item.file);
}
}
function uploadFile (file) {
if (file) {
var xhr = new XMLHttpRequest();
var fd = new FormData();
fd.append('image',file);
xhr.upload.addEventListener("error", function (ev) {
console.log(ev);
}, false);
xhr.open("POST", "upload.php");
xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.setRequestHeader("X-File-Name", file.name);
xhr.send(fd);
}
}
php code upload.php
<?php
session_start();
if (!isset($_POST['description'])) {
echo "upload:fail\n";
echo "message:No scene was specified";
exit();
}
if (isset($_FILES['image'])) {
if(!move_uploaded_file($_FILES['image']['tmp_name'], "uploads/" . $_POST['description'] . "/" . $_FILES['image']['name'])) {
echo "upload:fail\n";
}
else {
echo "upload:succes\n";
}
exit();
}
exit();
?>

I'd really advise against creating your own asynchronous file upload functionality when there is a plethora of developers who have already programmed the same thing better. Check out these options:
Blueimp's jQuery file uploader
Uploadifive (Uploadify's HTML5 implementation)
I've used these two before and they work very well. For BlueImp, you can use this option to send additional form data:
$('#fileupload').fileupload({
formData: $('.some_form').serialize()
});
The above captures a form and serializes its inputs. Alternatively, you can populate an array or object using specific values (i.e. from specific elements in your DOM):
var array = new Array();
$('.description').each(function() {
array[this.id] = this.value;
});
You'd use IDs to link your files and descriptions.

Related

PHP not able to read JSON but writes extra lines in SQL

I have an HMTL form with 3 fields on it, Firstname, Lastname and image upload file. When submit is pressed it calls the following JS script.
//main function to be called on submit
function processData() {
var firstName = document.querySelector('#first-name'),
lastName = document.querySelector('#last-name'),
imageUser = document.querySelector('#image-user');
var formSubmitData = {
'firstName': firstName.value,
'lastName': lastName.value,
'imageUser': imageUser.value
};
var dataString = JSON.stringify(formSubmitData);
if (navigator.onLine) {
sendDataToServer(dataString);
} else {
saveDataLocally(dataString);
}
firstName.value = '';
lastName.value = '';
imageUser.value = '';
}
//called on submit if device is online from processData()
function sendDataToServer(dataString) {
var myRequest = new XMLHttpRequest();
//new code added so data is sent to server
//displays popup message - data sent to server
myRequest.onreadystatechange = function() {
if (myRequest.readyState == 4 && myRequest.status == 200) {
console.log('Sent to server: ' + dataString + '');
window.localStorage.removeItem(dataString);
} else if (myRequest.readyState == 4 && myRequest.status != 200) {
console.log('Server request could not be completed');
saveDataLocally(dataString);
}
}
myRequest.open("POST", "write_test.php", true);
//Send the proper header information along with the request
myRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
myRequest.send(dataString);
alert('Sent: ' + dataString + ''); //remove this line as only for example
}
As you will see it sends a POST request to the php page. The "datastring" is encoded as JSON.
I use the following PHP code to send the data to the SQL server, but all it does is create a blank record with no data but it does create a new record.
<?php
//TRYING NEW CODE TO EXTRACT DATA FROM dataString
$json = json_decode(file_get_contents("php://input"), true);
$data = json_decode($json, true);
echo '<pre>' . print_r($data, true) . '</pre>';
// INSERT into your contact table.
$sql="INSERT INTO contacts (firstName, lastName)VALUES('$firstName','$lastName')";
How do I get it to create records in SQL with data that has been submitted from the form??
I have no final solution as I don't have the form code. Hope you are ready to learn.
I'm worried about user image - don't send any image for testing, but a string (like path) or nothing, please.
js - change for double quotes:
var formSubmitData = {
"firstName" : firstName.value,
"lastName" : lastName.value,
"imageUser" : imageUser.value
};
php - leave only this
<?php
$data = json_decode(file_get_contents("php://input")); // test only version
print_r($data); // test only version
/*
and close the rest as a comment - SQL is fine, don't worry
$data = json_decode(file_get_contents("php://input",true)); // final ver
echo print_r($data, true); // final ver
...
*/
If you receive the right output, delete the trial version and good luck.
If not - go back to var formSubmitData to the values on the right - they are so naked ... without any quotes
And of course, take care of security (injection) and order, set the required at the inputs - you don't need empty submits

If image url not exist on server replace url with other (multiple time)

I made lastposter avatar for my forum system.
What i want : when user avatar img not exist change file type multiple time. Such example; if user_{userid}_avatar.png not exist change url to user_{user_id}_avatar.jpg and again it's not exist change to user_{userid}_avatar.gif and etc.({user_id} coming as php variable that's no matter).
<div class="lpavatar"><img src="/avatar/user_{user_id}.png"/></div>
<div class="lpavatar"><img src="/avatar/user_{user_id}.png"/></div>
<div class="lpavatar"><img src="/avatar/user_{user_id}.png"/></div>
You can do something like this:
Javascript:
var img_types = ['jpeg', 'gif', 'png'];
var avatar = '';
for(var i=0;i<img_types.length();i++) {
avatar = new File("/path/to/avtar." + img_types[i]);
// See if the file exists
if(avatar.exists()){
break;
}
}
PHP:
<?php
// put allowed image types in this array
$img_types = ['jpeg', 'gif', 'png'];
// avatar URL will be stored in here
$avatar = '';
// loop over the image_types array
foreach($img_types as $img_type) {
$avatar = '/path/to/user_{userid}_avatar.' . $img_type;
// check if the files exists
if(file_exists($avatar)) {
// exit the foreach loop, because we found the image
break;
}
}
?>
You can use a function like this.
function image_exists(image_url){
var http = new XMLHttpRequest();
http.open('HEAD', image_url, false);
http.send();
return http.status != 404;
}

how do you connect an ajax post to a specific conditional in PHP file?

So i have written a function that is called onclick in my html file that uses AJAX, but i would like for this post to go to a specific table in mysql.
$('#submitIFC').click(function(e) {
var request;
if (window.XMLHttpRequest) {
request = new XMLHttpRequest();
} else {
request = new ActiveXObject("Microsoft.XMLHTTP");
}
var opinionIFC = $('ul.sort').sortable('toArray').join(',');
request.onreadystatechange = function() {
if ((request.readyState===4) &&(request.status===200)) {
var return_data = request.responseText;
document.getElementById('rank_ul').innerHTML= 'return_data';
// Preventing the default action triggered by clicking on the link
e.preventDefault();
e.preventDefault();
}//end of if
}//end of onreadystatechange function
//send requested movie to php file which will send to the external server
request.open("POST", "results.php", true);
request.send(opinionIFC);
document.getElementById('rank_ul').innerHTML='<img src="ajax-loader.gif">';
});
however there seems to be an issue with connecting this to my php if conditional, i tried copying the contents on my request.send(), like so
if($_POST['opinionIFC'])
{echo
// The data arrives as a comma-separated string,
// so we extract each post ids:
$data=explode(',',str_replace('li','',$_POST['sortdata']));
// Getting the number of objects
list($tot_objects) = mysql_fetch_array(mysql_query("SELECT COUNT(*) FROM sort_objects"));
if(count($data)!=$tot_objects) die("Wrong data!");
foreach($data as $k=>$v)
{
// Building the sql query:
$str[]='('.(int)$v.','.($tot_objects-$k).')';
}
$str = 'VALUES'.join(',',$str);
// This will limit voting to once a day per IP:
mysql_query(" INSERT INTO `sort_votes` (ip,date_submit,dt_submit)
VALUES ('".$_SERVER['REMOTE_ADDR']."',NOW(),NOW())");
// If the user has not voted before today:
if(mysql_affected_rows($link)==1)
{
mysql_query(' INSERT INTO `sort_objects` (id,votes) '.$str.'
ON DUPLICATE KEY UPDATE votes = votes+VALUES(votes)');
}
}
why isnt the ajax post request filtering through to my php file?
thank you so much, any help is much appreciated.
You're not sending opinionIFC parameter, try:
request.send('opinionIFC=' + opinionIFC);
You also need to set Content-type
request.setRequestHeader("Content-type","application/x-www-form-urlencoded");

Trying to upload images without refreshing page with javascript, not working

I am trying to upload images to my server via an html-form without refreshing the page. My problem is the files arent getting uploaded and I cant figure out why.
Javascript code:
function uploadFiles(event) {
var fileSelect = document.getElementById('file');
var files = fileSelect.files;
var formData = new FormData();
for (var i = 0; i < files.length; i++) {
var file = files[i];
if (!file.type.match('image.*')) {
alert("File: " + file.name + " is not an image and will not be uploaded.");
continue;
}
formData.append('images[]', file, file.name);
}
var xhr = new XMLHttpRequest();
xhr.open('POST', '../htdocs/Php/upload_file.php', true);
xhr.onload = function () {
if (xhr.status === 200) {
// File(s) uploaded.
alert('files uploaded');
} else {
alert('An error occurred!');
}
};
xhr.send(formData);
}
HTML code:
<form action="../htdocs/Php/upload_file.php" method="post" enctype="multipart/form-data">
<input type="file" name="images[]" id="file" onchange="uploadFiles()" multiple required />
</form>
PHP code:
$numberOfFiles = count($_FILES['images']['name']);
for($id = 0; $id < $numberOfFiles; $id++)
{
if (!file_exists("../UploadedImages/" . $_FILES["images"]["name"][$id])) {
move_uploaded_file($_FILES["images"]["name"][$id], "../UploadedImages/" . $_FILES["images"]["name"][$id]);
}
}
Looks like your JavaScript is correct, but your PHP needs some attention. I modified your php so that it first check to see if $_FILES were passed. Then where you had some incorrect logic was in your !file_exists() statement and how you move and check the file name.
To check if a file exists, and to move the file you need to use $_FILES['images']['tmp_name']. The 'name' attribute is just the name of the file uploaded, not the physical file uploaded to the browser.
To really test your code, use firebug and look at the console. It should return a line that you can expand and look at what was posted and what was returned.
Here is an example, the following code i gave you returns this:
C:\filepath\binaries\tmp\phpDB53.tmp Was Succesuflly uploaded
C:\filepath\binaries\tmp\phpDB54.tmp Was Succesuflly uploaded
C:\filepath\binaries\tmp\phpDB55.tmp Was Succesuflly uploaded
C:\filepath\binaries\tmp\phpDB56.tmp Was Succesuflly uploaded
NOTE: Double check that the files paths are absolutely correct. When checking firebug console, the php file will also return file errors as well, given that you have php error reporting on.
//Check if files were passed through to your ajax page
if(isset($_FILES)) {
$numberOfFiles = count($_FILES['images']['name']);
for($id = 0; $id < $numberOfFiles; $id++)
{
if (file_exists($_FILES["images"]["tmp_name"][$id])) {
move_uploaded_file($_FILES["images"]["tmp_name"][$id], $_FILES["images"]["name"][$id]);
echo $_FILES["images"]["tmp_name"][$id] . " Was Succesuflly uploaded \r\n ";
} else {
echo "file didnt exists " . $_FILES["images"]["tmp_name"][$id] . "\r\n ";
}
}
} else {
//No Files were passed through
echo "no files passed through";
}
exit();
Hopefully that answers your question.

How to download multiple files in one shot in IE

I want to download multiple files on click of a button in jsp.
I am using the following code in the js to call one servlet twice.
var iframe = document.createElement("iframe");
iframe.width = iframe.height = iframe.frameBorder = 0;
iframe.scrolling = "no";
iframe.src = "/xyz.jsp?prodId=p10245";
document.getElementById("iframe_holder").appendChild(iframe);
var iframe2 = document.createElement("iframe");
iframe2.width = iframe2.height = iframe2.frameBorder = 0;
iframe2.scrolling = "no";
iframe2.src = "/xyz.jsp?prodId=p10243";
document.getElementById("iframe_holder").appendChild(iframe2);
In xyz.jsp i am calling the servlet which downloads the file from a path and send it on the browser.
Issue is that it is working safari,firefox but not in IE.
We cannot download multiple files with IE?
By design, non-user-initiated file downloads are blocked in IE. That inherently means that it should not be possible to download more than one file as the result of a single user-click.
I've used the following code to download multiple files in IE and Chrome
function downloadFile(url)
{
var iframe = document.createElement("iframe");
iframe.src = url;
iframe.style.display = "none";
document.body.appendChild(iframe);
}
function downloadFiles(urls)
{
downloadFile(urls[0]);
if (urls.length > 1)
window.setTimeout(function () { downloadFiles(urls.slice(1)) }, 1000);
}
You pass an array of URLs to the downloadFiles() function, which will call downloadFile() for each with a short delay between. The delay seems to be the key to getting it to work!
I had a similar need but also wanted the downloads to occur in a new window.
I created a js to download a list of files, and a php to do the actual file saving. I used the above as a starting point, and the PHP start from (okay, can't find the original source). I encode the passed URI so spaces in the file names don't cause troubles.
(function () {
"use strict";
var files = [], // Array of filename strings to download
newWindow, // New window to handle the download request
secondsBetweenDownloads; // Wait time beteen downloads in seconds
//
// Download a file using a new window given a URI
//
function downloadFile(uri) {
if (!newWindow) {
newWindow = window.open('',
'',
'width=1500 height=100');
}
if (newWindow) {
newWindow.location =
'saveAs.php?' +
'file_source=' + encodeURI(uri);
newWindow.document.title = "Download File: " + uri;
} else {
console.log("Unable to open new window. Popups blocked?");
}
}
//
// Download all files specified in the files[] array from siteName.
// Download the file at array position zero, then set a timeout for
// secondsBetweenDownloads seconds
//
function downloadFiles(siteName) {
var showTime = new Date();
console.log(
showTime.toTimeString().substring(0,8) +
" Starting download for: " + files[0]
);
// Skip any empty entries, download this file
if (files[0].length > 0) downloadFile(siteName + files.splice(0, 1));
if (files.length > 0) { // If more files in array
window.setTimeout(function () { // Then setup for another iteration
downloadFiles(siteName );
}, secondsBetweenDownloads * 1000); // Delay for n seconds between requests
} else {
newWindow.close(); // Finished, close the download window
}
}
//
// Set the web site name and fill the files[] array with the files to download
// then kick off the download of the files.
//
$(document).ready(function () {
var
siteName** = "http://www.mysteryshows.com/thank-you/";
secondsBetweenDownloads** = 35; // N seconds delay between requests
files = [
"show1.mp3",
"show2.mp3"
];
downloadFiles(siteName, files);
});
}());
The HTML for the page is simple. Basically any syntax-compliant page will do.
The saveAs.php page which the js file uses in the newWindow.location line is php only.
<?php
if (isset($_GET['file_source'])) {
$fullPath = $_GET['file_source'];
if($fullPath) {
$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
$ext = strtolower($path_parts["extension"]);
switch ($ext) {
case "pdf":
header("Content-Disposition: attachment;
filename=\"".$path_parts["basename"]."\""); // use 'attachment' to
// force a download
header("Content-type: application/pdf"); // add here more headers for
// diff. extensions
break;
default;
header("Content-type: **application/octet-stream**");
header("Content-Disposition:
filename=\"".$path_parts["basename"]."\"");
}
if($fsize) {//checking if file size exist
header("Content-length: $fsize");
}
$request = $path_parts["dirname"] . '/' .
rawurlencode($path_parts["basename"]);
readfile($request);
exit;
}
}
?>
I used rawurlencode on just the 'basename' portion of the URI to ensure it was a valid, encoded request.
It can be done by creating a blob using the file source URL. I have tested this with image and PDF files in IE 11.
if (navigator.msSaveBlob) {
var xhr = new XMLHttpRequest();
xhr.open('GET', file_url, true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
var blob = this.response;
navigator.msSaveBlob(blob, file_name);
}
}
xhr.onerror = function(e) {
alert("Error " + e.target.status + " occurred while receiving the document.");
}
xhr.send();
}
I got this idea when I came across this: Getting BLOB data from XHR request

Categories

Resources