Progress Bar for file uploads to PHP using AJAX and Bootstrap - php

I have a form with which I upload images using AJAX to a PHP Script
This is my form
<form action ="upload.php" method = "POST" enctype = "multipart/form-data" class = "form-horizontal" name="formData" id="data">
<!--File Upload-->
<div class = "form-group">
<label class="control-label col-sm-1" for = "file">File:</label>
<div class="col-sm-9">
<input type = "file" name = "image_file" id = "image_file" class = "form-control" accept="image/*" onChange="autoPull(this.value)";>
</div>
</div>
<div class = "form-group">
<label class="control-label col-sm-1" for = "project_name">ProjectName:</label>
<div class="col-sm-9">
<input type = "text" name ="project_name" id = "project_name" class = "form-control" placeholder="Enter Project Name" value = "" required>
</div>
</div>
<div class = "button">
<div class="form-group">
<div class="col-sm-offset-1 col-sm-6">
<input type="submit" name = "submit" class="btn btn-primary" value = "Submit" id="file_upload">
<input type="reset" name = "submit" class="btn btn-default" value = "Reset">
</div>
</div>
</div>
</form>
<br/>
<div class="progress" style="display:none;">
<div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:0%;">
</div>
</div>
<div id = "result"></div>
The result div is where the output from PHP is displayed(see in AJAX)
Progress bar is where I wish to see my bootstrap progress bar.
and this is my AJAX
$(function () {
$('form#data').submit(function (e){
e.preventDefault();
e.stopImmediatePropagation();
var formData = new FormData($(this)[0]);
var file = $('input[type=file]')[0].files[0];
formData.append('upload_file',file);
$('.progress').show();
$.ajax({
xhr: function() {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
percentComplete = parseInt(percentComplete * 100);
$('.progress-bar').css('width',percentComplete+"%");
$('.progress-bar').html(percentComplete+"%");
if (percentComplete === 100) {
}
}
}, false);
return xhr;
},
type:'POST',
url: 'upload.php',
data: formData,
async:false,
cache:false,
contentType: false,
processData: false,
success: function (returndata) {
$('#result').html(returndata);
}
});
return false;
});
});
Now I get an output which shows me the data echoed in the PHP. But for some reason I cant get the progress bar to work.
What could be the issue?

This should do it
var progress_bar = $(".progress-bar");
progress_bar.html("0%");
progress_bar.css("width", 0);
$(".progress").hide();

removing
async : false;
solved it. But I need to see how to reset the bar now.

Related

Problem to insert into mysql with ajax and php

I want to insert in 2 tables of mysql, one table is about information of a product and the other one is for the images of those products.
I have this form
<form action="#" method="post" enctype="multipart/form-data" id="upload-multi-images">
<div class="form-group">
<label>Name</label>
<input type="text" name="name" class="form-control" required autocomplete="off">
</div>
<div class="form-group">
<label>Price</label>
<input type="text" name="price" class="form-control" required autocomplete="off">
</div>
<div class="form-group">
<label>Stock</label>
<input type="text" name="stock" class="form-control" required autocomplete="off">
</div>
<div class="row">
<div class="col-xl-2 col-lg-2 col-md-3 col-sm-4 col-xs-12" id="add-photo-container">
<div class="add-new-photo first" id="add-photo">
<span><i class="icon-camera"></i></span>
</div>
<input type="file" multiple id="add-new-photo">
</div>
</div>
<div class="button-container">
<button type="submit">Subir imágenes</button>
</div>
</form>
I get the images and the information with this JS
$(document).on("submit", "#upload-multi-images", function (e) {
e.preventDefault();
$(document).on("submit", "#upload-multi-images", function (e) {
var namePro = document.getElementsByName('name')[0].value;
var price = document.getElementsByName('price')[0].value;
var stock = document.getElementsByName('stock')[0].value;
formData.append('namePro', namePro);
formData.append('price', price);
formData.append('stock', stock);
e.preventDefault();
//Envio mediante Ajax
$.ajax({
url: "upload.php",
type: "post",
dataType: "json",
data: formData,
cache: false,
contentType: false,
processData: false,
beforeSend: function () {
loading(true, "Adding photo...");
},
success: function (res) {
loading(false);
if (res.status == "true") {
createImages(res.all_ids);
$("#Images form .row > div:not(#add-photo-container)").remove();
formData = new FormData();
} else {
alert(res.error);
}
},
error: function (e) {
console.log(e.responseText);
}
});
});
Then y send the images to this php to send them to mysql
$namePRO = $_REQUEST['namePro'];
$price = $_REQUEST['price'];
$stock = $_REQUEST['stock'];
$insertDatos = $conexion->prepare("INSERT INTO products (name , price, stock) VALUES (:name, :price, :stock)");
$wasUploadedDATA = $insertDatos->execute(array(
":name" => $namePRO,
":price" => $price,
":stock" => $stock,
));
$idPRO = $conexion->lastInsertId();
if (isset($_FILES) && !empty($_FILES)) {
$files = array_filter($_FILES, function($item) {
return $item["name"][0] != "";
});
foreach ($files as $file) {
$tmp_name = $file["tmp_name"];
$name = $file["name"];
$path = "/images/$name";
$pathSYS = "/var/www/html/images/$name";
$insertImages = $conexion->prepare("INSERT INTO product_files (id_pro, name, web_path, system_path) VALUES (:idPRO, :name, :path, :pathSYS)");
$wasUploaded = $insertImages->execute(array(
":name" => $name,
":idPRO" => $idPRO,
":path" => $path,
":pathSYS" => $pathSYS,
));
if ($wasUploaded) {
$id = $conexion->lastInsertId();
$data["all_ids"]["id_$id"]["id"] = $id;
$data["all_ids"]["id_$id"]["name"] = $name;
move_uploaded_file($tmp_name, "images/$name");
}
else {
die("There was an error. Please contact with the admin.");
}
}
}
I also have these other JS but I think they are not very important
function getRandomString(length) {
var text = "";
var possible =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < length; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
function createPreview(file, id) {
var imgCodified = URL.createObjectURL(file);
var img = $('<div class="col-xl-2 col-lg-2 col-md-3 col-sm-4 col-xs-12"
id="'
+ id + '"><div class="image-container"> <figure> <img src="' + imgCodified +
'" alt="Foto del usuario"> <figcaption> <i class="icon-cross"></i>
</figcaption> </figure> </div></div>');
$(img).insertBefore("#add-photo-container");
}
function createImages(all_ids) {
for (const key in all_ids) {
var image = all_ids[key];
var img = $('<div class="col-xl-2 col-lg-2 col-md-3 col-sm-4 col-xs-12"
data-id="' + image.id + '"><div class="image-container"> <figure> <img
src="images/' + image.name + '" alt="Foto del usuario"> <figcaption> <i
class="icon-cross"></i> </figcaption> </figure> </div></div>');
$("#my-images").append(img);
}
}
function showModal(card) {
$("#" + card).show();
$(".modal").addClass("show");
}
function closeModal() {
$(".modal").removeClass("show");
setTimeout(function () {
$(".modal .modal-card").hide();
}, 300);
}
function loading(status, tag) {
if (status) {
$("#loading .tag").text(tag);
showModal("loading");
}
else {
closeModal();
}
}
function showMessage(message) {
$("#Message .tag").text(message);
showModal("Message");
}
I don't have all of your code, but I've identified the issue in your code and I'll just add add the fix here for you.
First of all, if you are using jquery, it's better to write your code in a unified format and use jquery everywhere and not switch between jquery and plain JavaScript.
Having that said, instead of using document.getElementsByName you can easily add id attribute to your html element and access them with $('#<id>') way in jquery.
Second, even if you are using javascript to grab your html element data, what you are doing is wrong. var namePro = document.getElementsByName('name'); will select the whole html <input> object and not it's value. So you have to change it to: document.getElementsByName("name")[0].value
So you have 2 options:
1- Use what you have already and just change it a bit to:
var namePro = document.getElementsByName('name')[0].value;
var price = document.getElementsByName('price')[0].value;
var stock = document.getElementsByName('stock')[0].value;
2- Or for switching to jquery, you need to add id to all of these elements in your html:
<div class="form-group">
<label>Name</label>
<input type="text" id="name" name="name" class="form-control" required autocomplete="off">
</div>
<div class="form-group">
<label>Price</label>
<input type="text" id="price" name="price" class="form-control" required autocomplete="off">
</div>
<div class="form-group">
<label>Stock</label>
<input type="text" id="stock" name="stock" class="form-control" required autocomplete="off">
</div>
And then change you JavaScript to:
formData.append('name', $('#name').val());
formData.append('price', $('#price').val());
formData.append('stock', $('#stock').val());
Update:
The sample code which works on my machine is like this:
HTML:
<form action="#" method="post" enctype="multipart/form-data" id="upload-multi-images">
<div class="form-group">
<label>Name</label>
<input type="text" name="name" class="form-control" required autocomplete="off">
</div>
<div class="form-group">
<label>Price</label>
<input type="text" name="price" class="form-control" required autocomplete="off">
</div>
<div class="form-group">
<label>Stock</label>
<input type="text" name="stock" class="form-control" required autocomplete="off">
</div>
<div class="row">
<div class="col-xl-2 col-lg-2 col-md-3 col-sm-4 col-xs-12" id="add-photo-container">
<div class="add-new-photo first" id="add-photo">
<span><i class="icon-camera"></i></span>
</div>
<input type="file" multiple id="add-new-photo">
</div>
</div>
<div class="button-container">
<button type="submit">Subir imágenes</button>
</div>
</form>
JS #1:
var formData = new FormData();
$(document).ready(function(){
$(".modal").on("click", function (e) {
console.log(e);
if (($(e.target).hasClass("modal-main") || $(e.target).hasClass("close-modal")) && $("#loading").css("display") == "none") {
closeModal();
}
});
$(document).on("click", "#add-photo", function(){
$("#add-new-photo").click();
});
$(document).on("change", "#add-new-photo", function () {
var files = this.files;
var element;
var supportedImages = ["image/jpeg", "image/png", "image/gif"];
var InvalidElementFound = false;
for (var i = 0; i < files.length; i++) {
element = files[i];
if (supportedImages.indexOf(element.type) != -1) {
var id = getRandomString(7);
createPreview(element, id);
formData.append(id, element);
}
else {
InvalidElementFound = true;
}
}
if (InvalidElementFound) {
showMessage("Invalid Elements Found.");
}
else {
showMessage("All the files were uploaded succesfully.");
}
});
$(document).on("click", "#Images .image-container", function(e){
var parent = $(this).parent();
var id = $(parent).attr("id");
formData.delete(id);
$(parent).remove();
});
$(document).on("submit", "#upload-multi-images", function (e) {
e.preventDefault();
var namePro = document.getElementsByName('name')[0].value;
var price = document.getElementsByName('price')[0].value;
var stock = document.getElementsByName('stock')[0].value;
formData.append('namePro', namePro);
formData.append('price', price);
formData.append('stock', stock);
//Envio mediante Ajax
$.ajax({
url: "upload.php",
type: "post",
dataType: "json",
data: formData,
cache: false,
contentType: false,
processData: false,
beforeSend: function () {
loading(true, "Adding photo...");
},
success: function (res) {
console.log('success');
console.log(res);
loading(false);
if (res.status == "true") {
createImages(res.all_ids);
$("#Images form .row > div:not(#add-photo-container)").remove();
formData = new FormData();
} else {
alert(res.error);
}
},
error: function (e) {
console.log('error');
console.log(e.responseText);
}
});
});
$(document).on("click", "#MyImages .image-container", function (e) {
var parent = $(this).parent();
var id = $(parent).attr("data-id");
var data = {
id : id
}
$.post("delete.php", data, function(res) {
if (res == "true") {
showMessage("¡Images successfully removed!");
$(parent).remove();
}
else {
showMessage("Sorry, there was an error uploading the images.");
}
});
});
});
JS #2:
function getRandomString(length) {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < length; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}
function createPreview(file, id) {
var imgCodified = URL.createObjectURL(file);
var img = $('<div class="col-xl-2 col-lg-2 col-md-3 col-sm-4 col-xs-12" id="'+ id + '"><div class="image-container"> <figure> <img src="' + imgCodified + '" alt="Foto del usuario"> <figcaption> <i class="icon-cross"></i></figcaption> </figure> </div></div>');
$(img).insertBefore("#add-photo-container");
}
function createImages(all_ids) {
for (const key in all_ids) {
var image = all_ids[key];
var img = $('<div class="col-xl-2 col-lg-2 col-md-3 col-sm-4 col-xs-12" data-id="' + image.id + '"><div class="image-container"> <figure> <img src="images/' + image.name + '" alt="Foto del usuario"> <figcaption> <i class="icon-cross"></i> </figcaption> </figure> </div></div>');
$("#my-images").append(img);
}
}
function showModal(card) {
$("#" + card).show();
$(".modal").addClass("show");
}
function closeModal() {
$(".modal").removeClass("show");
setTimeout(function () {
$(".modal .modal-card").hide();
}, 300);
}
function loading(status, tag) {
if (status) {
$("#loading .tag").text(tag);
showModal("loading");
}
else {
closeModal();
}
}
function showMessage(message) {
$("#Message .tag").text(message);
showModal("Message");
}
PHP: (upload.php)
$arr_ajax = array();
$arr_ajax['namePro'] = $_REQUEST['namePro'];
$arr_ajax['price'] = $_REQUEST['price'];
$arr_ajax['stock'] = $_REQUEST['stock'];
if (isset($_FILES) && !empty($_FILES)) {
$files = array_filter($_FILES, function($item) {
return $item["name"][0] != "";
});
$iCnt = 0;
foreach ($files as $file) {
$arr_ajax['Filename'.$iCnt] = $file["name"];
$iCnt++;
}
}
echo json_encode($arr_ajax);
And with this code, when I click on Submit button, I get the following response in my browser console:
index.html:79 success
index.html:80 {namePro: "Test Product", price: "100.00", stock: "15", Filename0: "faces1.jpg"}

How to get CKEditor value in Codeigniter?

I Want to receive the values from the CKEditor. I Have written this HTML code
<div class="col-md-12">
<div class="form-group">
<label for="Image" class="control-label">Item Description </label>
<textarea id="item_description" name="item_description" rows="10" cols="80" style="resize:none"></textarea>
</div>
<!-- /.form-group -->
</div>
<div class="col-md-2">
<input type="submit" name="submit" id="Add" value="Add Items" class="btn btn-success">
</div>
This is the JQuery Code to get the value of the CKEditor
$("#Add").on("click", function(e) {
e.preventDefault();
var item_description = CKEDITOR.instances["item_description"].getData();
var formData = new FormData($("#form1")[0]); //It automatically collects all fields from form
$.ajax({
url: "'.base_url().'Home/add_items",
type: "post",
data: formData,
success: function(output) {
alert('Added'):
}
});
});
And this the Home controller but when I here access the item_description
value is empty.
<?php
class Home extends MY_Controller
{
public function add_items()
{
echo $title = $this->input->post('item_description');
//$this->show('admin/add_items.php');
}
}
?>
Modify your javascript codes, like this :
$("#Add").on("click", function(e) {
e.preventDefault();
var formData = new FormData($("#form1")[0]); //It automatically collects all fields from form
formData.append('item_description', CKEDITOR.instances['item_description'].getData());
$.ajax({
url: "<?=base_url()?>Home/add_items",
type: "post",
data: formData,
success: function(output) {
alert(output);
}
});
});

Getting a null value in my input file type field

I downloaded a web application and i found out that it is created using Smarty Template Engine. I want to add an avatar field when creating new company so i added enctype="multipart/form-data" and <input type="file" name="avatar"> to the existing <form> and i also added avatar to my companies table in my database. Here is the HTML code:
<form class="form-horizontal" id="ib_modal_form" enctype="multipart/form-data">
<div class="form-group"><label class="col-lg-4 control-label" for="company_name">{$_L['Company Name']}<small class="red">*</small></label>
<div class="col-lg-8"><input type="text" id="company_name" name="company_name" class="form-control" value="{$val['company_name']}"></div>
</div>
<div class="form-group"><label class="col-lg-4 control-label" for="avatar">{$_L['Avatar']}</label>
<div class="col-lg-8"><input type="file" name="avatar"></div>
</div>
<div class="form-group"><label class="col-lg-4 control-label" for="email">{$_L['Email']}</label>
<div class="col-lg-8"><input type="text" id="email" name="email" class="form-control" value="{$val['email']}"> </div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" data-dismiss="modal" class="btn btn-danger">{$_L['Cancel']}</button>
<button class="btn btn-primary modal_submit" type="submit" id="modal_submit"><i class="fa fa-check"></i> {$_L['Save']}</button>
</div>
I found out that the form goes to this javascript code when clicking the Save Button:
$modal.on('click', '.modal_submit', function(e){
e.preventDefault();
$.post( _url + "contacts/add_company_post/", $("#ib_modal_form").serialize())
.done(function( data ) {
if ($.isNumeric(data)) {
location.reload();
}
else {
$modal.modal('loading');
toastr.error(data);
}
});
});
Here is the code in the Controller:
case 'add_company_post':
$data = ib_posted_data();
$company = Model::factory('Models_Company')->create();
$company->company_name = $data['company_name'];
$company->url = $data['url'];
$company->email = $data['email'];
$company->phone = $data['phone'];
$company->logo_url = $data['logo_url'];
$company->avatar = $_FILES['avatar']['name'];
$company->save();
break;
The problem is that it does not recognize $_FILES['avatar']['name']; in the Controller Whenever i add a new company, i get a NULL value in my database. I cant seem to solve this problem. Any help would be appreciated. Thanks.
Change
From
$("#ib_modal_form").serialize()
To
new FormData($("#ib_modal_form")[0])
You should use FormData for uploading files using ajax. $(form).serialize() will give you just key and value.
Can you change your ajax call below way
$modal.on('click', '.modal_submit', function(e){
e.preventDefault();
var formData = new FormData($("#ib_modal_form")[0]);
$.ajax({
url: _url + "contacts/add_company_post/",
type: 'POST',
data: formData,
cache: false,
contentType: false,
processData: false,
success: function (data) {
if ($.isNumeric(data)) {
location.reload();
}
else {
$modal.modal('loading');
toastr.error(data);
}
},
});
});

I wanna display json data to a card in html page using ajax

Output of my requirement
I have tried many times to get the required result in html page.
am calling a function when i check a box in html ,the function giving back result of json data and this json data i wanna display dynamically into my card style.
Here is hmtl code:
<div id="filter"style="margin-top:100px;margin-left:100px">
<h2>Filter options</h2>
<div>
<input type="checkbox" id="Samsung" checked>
<label for="Samsung">Samsung</label>
</div>
<div>
<input type="checkbox" id="iPhone" checked>
<label for="iPhone">iPhone</label>
</div>
<div>
<input type="checkbox" id="HTC" checked>
<label for="HTC">HTC</label>
</div>
<div>
<input type="checkbox" id="LG" checked>
<label for="LG">LG</label>
</div>
<div>
<input type="checkbox" id="Nokia" checked>
<label for="Nokia">Nokia</label>
</div>
</div>
<table id="phones" >
<thead>
</thead>
<tbody >
<div style="margin-top:100px;margin-left:100px;margin-right:100px" >
<div>
<label style="margin-bottom:50px;margin-left:80px"><h2>Find your best hotel</h2></label>
</div>
<div class="col-xs-12 col-sm-4" style="background-color:lavender;height:310px;width:310px"><label id="hotel_image"></label></div>
<div class="col-xs-12 col-sm-6" style="background-color:lavenderblush;"><label id="hotel_name"></label></div><br>
<div class="col-xs-12 col-sm-3" style="background-color:lavender;margin-left:100px;margin-top:10px"><label id="hotel_price"></label></div>
<div class="col-xs-12 col-sm-3" style="background-color:#ccc;margin-top:220px;margin-left:300px"><label id="book_me"></label></div>
</div>
</tbody>
</table>
Here is javascript code:
<script>
function getPhoneFilterOptions(){
var opts = [];
$checkboxes.each(function(){
if(this.checked){
opts.push(this.id);
}
});
return opts;
}
function updatePhones(opts){
$.ajax({
type: "POST",
url: "submit.php",
dataType : 'json',
cache: false,
data: {filterOpts: opts},
success: function(data){
$.each(data, function() {
$.each(this, function(k , v) {
if(k==='img_path'){
v = "<a href='image_description.html'><image src='img_path' height='300px' width='300px' ></a>";
("#hotel_image").html(v);
} else if (k==='price'){
("#hotel_price").html(v);
} else if (k==='brand'){
("#hotel_name").html(v);
}
})
});
}
})
}
var $checkboxes = $("input:checkbox");
$checkboxes.on("change", function(){
var opts = getPhoneFilterOptions();
updatePhones(opts);
});
$checkboxes.trigger("change");
</script>
am geeting data json data from submit.php like this:
[
{
"img_path":"photo1.jpg",
"price":"2000",
"brand":"AAMSOTO"
},
{
"img_path":"photo4.jpg",
"price":"2500",
"brand":"AfMSOTO"
},
{
"img_path":"photo2.jpg",
"price":"3000",
"brand":"CAMSOTO"
},
{
"img_path":"photo3.jpg",
"price":"4000",
"brand":"BAMSOTO"
}
]
Assuming data is a javascript object the following inside your success method should work:
Make sure data is a javascript object, if its not you will have to use JSON.parse() to turn the JSON data into one.
$.each(data, function() {
var imageUrl = this['img_path']
var price = this['price']
var brand = this['brand']
const img = document.createElement('img');
img.src = imgUrl;
document.getElementById('#hotel_image').appendChild(img);
document.getElementById('#hotel_price').appendChild(document.createTextNode(price));
document.getElementById('#hotel_name').appendChild(document.createTextNode(brand));
}

ajax submit form with file

I have form, with ajax, that contain textarea and upload file field
I can submit only one of them.
how can I fix that?
I want to send "info" + "filesData" to the server.
Please advise.
Thank you in advanced
AJAX :
$(function() {
$("#submit").click(function() {
var file_data = $('#files').prop('files')[0];
var form_data = new FormData();
form_data.append('file', file_data);
var files_data = form_data;
alert(files_data);
var act = 'add';
var $form = $("#addCommentForm");
var info = $form.serialize();
info += '&act=' + act ;
alert(info);
$.ajax({
type: "POST",
url: "ajax/addPost.php",
dataType: 'text', // what to expect back from the PHP script, if anything
cache: false,
contentType: false,
processData: false,
data: files_data,
success: function(data)
{
// alert(data); // show response from the php script.
$('#commentsBox').html(data);
$("#addCommentForm")[0].reset();
}
});
return false;
});
});
HTML:
<form class="form-horizontal" action='#' method="post" id="addCommentForm" enctype="multipart/form-data">
<div class="form-group">
<div class="col-md-8 col-xs-12">
<textarea class="form-control" name="post[text]"></textarea>
</div>
</div>
<div class="form-group">
<div class="col-md-8 col-xs-12">
<input type="file" class="form-control" name="file" id="files">
</div>
</div>
<div class="form-group">
<label class="col-xs-2 control-label" for="textinput"></label>
<div class="col-md-8 col-xs-12">
<a class="btn btn-primary" id="submit">submit</a>
</div>
</div>
</form>
PHP
print_r ($_FILES);
print_r ($_POST);
In $.ajax call, subtitute the value of data parameter (filesData) by:
{ field1 : field1value, field2 : field2value, .... }
use as many field/value pairs as you need
you also can get the values directly like this:
{ field1 : $('#commentsBox').text(), field2 : $('#yourinput').val(), .... }

Categories