sending array of edited array of files(images) to php script - javascript

I have a form containing an input of type file that can accept multiple files(images) as shown below:
<input type="file" id="fileupload" name="fileupload[]" multiple />
Once a user selects an image or multiple images they are added dynamically to the website and also the user can remove one or all of them if he wants to.
Is there a way I can update which files are chosen from the input element to send to php script?
If not how can I send only images the user chooses? I mean I can put what the user chose in another array in JavaScript but how can I send them to php script?
Edited
In more details for example when the user chooses three image files there is JavaScript code i use that appends them into screen as images and the user is given the option to remove one or all of them by clicking on them. So my problem is if the user for example removed one of the images how can I send only the other two images into the php script?
I am not looking for complete code. I am just looking for a hint on how to accomplish it.

I've understood what you want.
Combine Ajax with formData to get that.
$(document).ready(function(){
$("form#data").submit(function(){
// create your filtred list of files from your file input
var data = {};
$.each($('#fileupload')[0].files, function(i, file) {
// Keep only the files that the user has selected
if ( i % 2 == 0){ // <--- CHANGE THIS
data['file-'+i] = file;
}
});
// create a FormData (to send files with AJAX)
var formData = new FormData();
for (var key in data) {
formData.append(key, data[key]);
}
// send that formData
php_script_url = "your_script.php"
$.ajax({
url: php_script_url,
type: 'POST',
data: formData,
async: false,
success: function (data) {
console.log(data);
},
cache: false,
contentType: false,
processData: false
});
return false;
});
});
Don't forget to include jQuery before this script
<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>

Related

Run PHP, wait; run JavaScript, wait; then submit form?

What I need to do:
I have an upload form with a file input and hidden text inputs. The user uploads an image, the image gets manipulated and then sent to remote server for processing which takes a few seconds, then the remote server sends the finalized images back to the home server where they are saved in a new folder. JavaScript needs to reach these new images to do further data processing on the newly saved images (which also takes a second). Only after JavaScript has done its thing and updated the form's input variables can the form be submitted.
Right now I've got all of the separate pieces working, but executing everything in one click has proven to be a challenge.
My code for uploading the images:
PHP:
if(isset($_POST['submit'])){
//do image manipulation and save new files using PHP
}
JS:
function furtherProcessing() {
//do further processing on newly saved images in newly created directory,
//update hidden input variables for the form
}
PHP again:
if(isset($_POST['input_variables'])){
//send these variables to SQL database
}
I know trying to use JavaScript to get the newly saved images isn't an ideal approach, but the framework that I'm using is only available in JavaScript. Is this even possible with one click?
You can do this:
In your HTML, add data-processed="false" to your form like this:
<form action="upload.php" method="post" name="q_data" data-processed="false" enctype="multipart/form-data">
In your jQuery call this to submit the images via ajax:
$("form[name='q_data']").submit(function(e) {
var $this = $(this);
var processed = $this.data('processed')
if (processed == false) {
e.preventDefault();
var formData = new FormData($(this)[0]);
$.ajax({
url: "upload.php",
type: "POST",
data: formData ,
async: false,
success: function(msg) {
//alert(msg);
if (msg !== 'success') {
$this.data('processed', true)
furtherProcessing();
}
},
cache: false,
contentType: false,
processData: false
});
}
});
function furtherProcessing() {
//do further processing on newly saved images in newly created directory,
//update hidden input variables for the form
$("form[name='q_data']").submit();
}
In some-page.php do this:
if(isset($_POST['some-image-input-name'])){
//do image manipulation and save new files using PHP
return 'success'
}
However, if it were me, I'd have that first ajax call (that saves the images) simply return the urls for the saved images, then there is no need for a second ajax call to retrieve them which I assume is what you are doing now

Cropping an image on rails

I have the following data both in my js file or as a param in rails. Togther there is an image that is to be sent to server, what I want to achieve is to crop the image based on the data such as below. I am not allowed to use gems :) just using ruby/js code if I can manipulate the image already in js side. I am using cropper js which generated the output to me. What should I do to achieve cropping ?
{"x":552.697358490566,"y":-72.49509433962258,"width":696.9599999999999,"height":696.9599999999999,"rotate":0,"scaleX":1,"scaleY":1}
Check out the fiddle: Link
This is the code you should be using, since your JSON is already formatted the same way Cropper takes its input:
//get the data from your rails framework and save it in a variable, below I just pasted the same data you put in your question
var data = {"x":552.697358490566,"y":-72.49509433962258,"width":696.9599999999999,"height":696.9599999999999,"rotate":0,"scaleX":1,"scaleY":1};
//remember to change my-picture to the id of your img
$('#my-picture').cropper('setData', data);
//also make sure to bind this to your own button
$('#crop-button').click(function(e){
//this will transform the image into a blob, so you can submit it in form data
$(this).href = $('#my-picture').cropper("getCroppedCanvas").toBlob(function (blob) {
var formData = new FormData();
formData.append('croppedImage', blob);
//this is where you put your Rails path to upload
//it's going to be a POST, so you should know how to handle it
$.ajax('/path/to/upload', {
method: "POST",
data: formData,
processData: false,
contentType: false,
success: function () {
console.log('Upload success');
},
error: function () {
console.log('Upload error');
}
});
});
});

html input file - how to save selected file when selecting new file?

I'm trying to create an upload panel like facebook, but I've got a trouble with <input type="file" />.
Here is facebook upload image panel:
My trouble is: if I click add more (like image above), that means the <input type="file" /> will be clicked again. So, the value will be overridden.
After that, if I click submit button, only 1 image can be uploaded.
My jquery code to upload looks like this:
function Upload(evt, id)
{
var file = document.getElementById("file");
var formData = new FormData();
for (i = 0; i < file.files.length; i++) {
formData.append(file.files[i].name, file.files[i]);
}
formData.append("id", id);
$.ajax({
url: "/Home/Upload",
type: "POST",
dataType: "json",
data: formData,
contentType: false,
processData: false,
success: function (data) {
alert('upload successful...');
},
error: function () {
alert('upload failed...');
}
});
}
The first line: var file = document.getElementById("file");. It means: get the latest value of <input type="file" name="file" id="file" /> (no keep the selected file before).
Can you tell me how to get all the selected files? (I don't talk about multiple).
Thank you!
"My trouble is: if I click add more (like image above), that means the will be clicked again. So, the value will be overridden."
Here's the underlying problem with your script:
"You can't set the value of a file picker from a script" so no direct manipulation of form will work
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#File_inputs
You can't manipulate file inputs from javascript in any meaningful way (for obvious security reasons), you can only read them. However, you can manipulate the DOM. What facebook and other multi-part pickers actually do is create and destroy file input elements in order to allow the flows they want, rather than try to bind anything to the file value of the input.
There are a lot of plugins that handle this complexity for you, but it's pretty doable to get it working once you understand the problem you're working around.
further clarification:
yup, it sounds like you're thinking about it right now! just think of file inputs as read-only, and use another variable to store all your values, and any function to deal with showing previews in the dom reads from that rather than binding directly from the file input.
One extra thing I would add in response to But the value can only append, not remove :((, is that you shouldn't store the values in FormData if you might need to remove values. Instead just use a regular object to store all the values you want to add/modify, and then construct the object when the user submits the form. Something along the lines of this:
var myFormDataObject = {}; // can store inputs in this
// watch onchange and add/remove from myFormDataObject
function sendStuff(){
var formData = new FormData();
for (var key in myFormDataObject) {
formData.append(key, myFormDataObject[key]);
}
// then post/put/patch/etc the form
}

Krajee file-input submit files on form submit

I am using this plugin for bootstrap to upload files which is stored in a form with submit button
http://plugins.krajee.com/file-input/
My question is -
a) is there a method or something to either check if there are files in the dropZone that are still not uploaded and notify a user after he submits a form that he didn't uploaded the files
b) is there a method that will trigger the upload when the submit button is fired?
Now it looks like this - if I submit my form it wont upload the files and just pass the form, I have to manually click upload files then submit the form
Maybe some of you came across this issue cause I am not able to figure it out myself due to poor documentation.
I found a work around for this issue.
<input id="input-photos" name="Photos" multiple type="file" class="file-loading">
Define a global variable in Javascript:
var formData = new FormData();
Append the selected files to formData on filePreUpload action.
$('#input-photos').on('filebatchpreupload', function(event, data, previewId, index) {
var form = data.form, files = data.files, extra = data.extra,
response = data.response, reader = data.reader;
$.each(files, function (key, value) {
if(value != null){
formData.append("Photos", value, value.name);
}
}); });
On form submission append all form fields and post the form through ajax.
$('#yourForm').submit(function() {
$('#input-photos').fileinput('upload');
var model_data = $("#yourForm").serializeArray();
$.each(model_data,function(key,input){
formData.append(input.name,input.value);
});
$.ajax({
url: "#Url.Action("Save", "Home")",
type: "POST",
datatype: "json",
data: formData,
processData: false, // tell jQuery not to process the data
contentType: false, // tell jQuery not to set contentType
success: (function (result){
window.location.href = '#Url.Action("Index", "Home")';
}),
error: function (xhr) {
alert("Error: " + xhr.statusText);
}
});
return false;
});
Validation of required property for form based upload (non ajax) scenario, which will enforce files to be selected and required before upload. This scenario includes custom form submit and reset buttons for upload (and default upload and remove buttons are hidden). The upload will force a file to be selected and required - else a validation error as set in msgRequired will be shown.
Try it:-
https://plugins.krajee.com/file-count-validation-demo#required-non-ajax-1

Ajax request 'onError' handler

There is one feature on my site: delete without page refresh. The user just presses 'delete' and the browser will send Ajax-request. It will load 'delete' script with id parameter.
All work well. But it is not very good because of referential integrity of the database. For example, It is possible to delete street, where some people are living.
I want to upgrade my script. I want to add a check to delete script and don't let delete data if some 'people' are connected to 'street' table.
jQuery handler of button click:
$('body').on('click', '.deleteStreet', function()
{
var id = $(this).attr('id');
var hideMe = $(this).parent().parent();
var dataString = 'id=' + id;
if(confirm("Are you sure you want to delete street? It is possible some people living there!"))
{
$.ajax({
type: "GET",
url: "/index.pl?mode=streets&action=delete",
data: dataString,
cache: false,
success: function(e)
{
hideMe.hide();
}
});
return false;
}
});
It will call script anyway and now will delete data anyway. I can add some checks to delete script now and it wouldn't delete, but jquery script would work anyway and will hide table row anyway (because request was send ok, without 404, etc)
1) Is it possible to see delete script result and hide or not hide row depending on it? For example, it will return true or false, js script will catch it and show message about deleting or not deleting of data depending on it.
2) This problem caused by structure of my site. There are some switches on index.pl and load appropriate scripts loading depending on query (mode=street then load street.pl, mode=user then load users.pl etc). So it will show all data loaded before delete.pl script and it will be impossible to check script returned true or false.
Any help? :) Thank you!
P.S.: I am very sorry for my awful english.
You can have the result of your ajax call in the first parameter of the success callback. ex:
$.ajax({
type: "POST",
url: "/index.pl?mode=streets&action=delete",
data: dataString,
cache: false,
success: function(e)
{
if(e === '1'){
hideMe.hide();
}
}
});
try to log your result in the console for tests: console.log(e).
For deleting data you should use a POST request ( or DELETE but not supported by all browsers).
I dont know how your datas (streets) looks like but an other way could it be to return all your existing streets in a json object on the delete request result. And refresh all lines.

Categories

Resources