I use croppie to crop photos on my website. I am able to crop and upload the image. But when I try to crop and upload without selecting an image, a black image is being uploaded. So how do I validate if the file upload is empty? (Note: I use Codeigniter)
HTML:
<div class="form-group">
<div id="upload-image"></div>
</div>
<div class="form-group">
<label for="">Select profile image:</label>
<input type="file" id="images" class="form-control">
<button class="btn btn-success cropped_image help-block"><i class="fa fa-floppy-o"></i> Save</button>
</div>
JS:
$image_crop = $('#upload-image').croppie({
enableExif: true,
viewport: {
width: 342,
height: 192,
type: 'square'
},
boundary: {
width: 380,
height: 250
}
});
$('#images').on('change', function () {
var reader = new FileReader();
reader.onload = function (e) {
$image_crop.croppie('bind', {
url: e.target.result
}).then(function(){
// console.log('<?php echo base_url() ?>');
});
}
reader.readAsDataURL(this.files[0]);
});
$('.cropped_image').on('click', function (ev) {
$image_crop.croppie('result', {
type: 'canvas',
size: { width: 1366, height: 768 }
}).then(function (response) {
$.ajax({
url: "<?php echo base_url() ?>Light/upload_home_bg",
type: "POST",
data: {"image":response},
success: function (data) {
alert(data);
$(location).attr('href','<?php echo base_url() ?>Light/home');
// html = '<img src="' + response + '" />';
// $("#upload-image-i").html(html);
}
});
});
});
PHP:
public function upload_home_bg()
{
$path = 'uploads/'.$this->data['account']->username.'/';
$croped_image = $_POST['image'];
list($type, $croped_image) = explode(';', $croped_image);
list(, $croped_image) = explode(',', $croped_image);
$croped_image = base64_decode($croped_image);
$image_name = time().'.png';
// upload cropped image to server
file_put_contents($path.$image_name, $croped_image);
$query = $this->db->query("select * from contents where user_id = '$this->user_id' and id = '$this->id' and meta_key = 'home_background_image'");
if ($query->num_rows() > 0)
{
$data['home_bg'] = $query->row();
$Bg = [
'value' => base_url().$path.$image_name
];
if ($this->Lights->update_home_background_image($Bg,$this->user_id,$data['home_bg']->content_id))
{
echo "Image successfully updated!";
}
}
else
{
$Bg = [
'user_id' => $this->user_id,
'id' => $this->id,
'business_name' => $this->BusinessName,
'meta_key' => 'home_background_image',
'content_title' => '',
'description' => '',
'value' => base_url().$path.$image_name
];
if ($this->db->insert('contents',$Bg))
{
echo "Image successfully uploaded!";
}
}
}
I tried doing this to check if the user selected an image:
if (!empty($_POST['image'])) {
# code...
}
But there are data being passed regardless if the user selected an image or not. Here is the data being passed (on the alert window): https://i.stack.imgur.com/DtqFD.png
Thanks in advance!
Okay. I finally managed to come up with a solution. What I did was to pass another value on my ajax var file_input = $('#images').val(); which gets the value of my file upload input.
JS:
$('.cropped_image').on('click', function (ev) {
$image_crop.croppie('result', {
type: 'canvas',
size: { width: 1366, height: 768 }
}).then(function (response) {
var file_input = $('#images').val();
$.ajax({
url: "<?php echo base_url() ?>Light/upload_home_bg",
type: "POST",
data: {"image":response,"file":file_input},
success: function (data) {
alert(data);
$(location).attr('href','<?php echo base_url() ?>Light/home');
}
});
});
});
Then on my php file, I check if the file is empty or not:
if (!empty($this->input->post('file')))
{
//Upload code
}
else
{
//Prompt user to select an image
}
late to the party - similar problem. I added this before the ajax:
...}).then(function (response) {
if(response.length < 2000){
if(! confirm("Did you load an image? It looks too small\n"+ response.length)) return;
}
FWIW an empty image for me is of length 1971
Related
Good morning all,
I am using materialize.css in a PHP app
I will want to initialize the auto-complete data with an API call.
The .autocomplete () initializes the data with a JSON array " data ":,
which I get with the .ajax ({..., url: '/search.php', ... datas}).
but I can't inject the datas into the.autocomplete (),
how can I do it?
Here is the source code:
<body>
<form action="">
<div class="row">
<div class="col s12">
<div class="row">
<div class="input-field col s6">
<i class="material-icons prefix">title</i>
<input id="searchOnAPI" name="name" type="text" class="autocomplete" value="{{ item.name }} ">
<label for="searchOnAPI">{{ siteData('admin.titre') }}</label>
<ul id="autocomplete-content" class="autocomplete-content"><li><a></a></li></ul>
</div>
</div>
</div>
</div>
</form>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
<script>
$(document).ready(function () {
$('#searchOnAPI').keyup(function () {
$('#autocomplete-content').html('');
let search = $(this).val();
if (search !== "") {
$.ajax({
type: 'GET',
url: '/search.php',
data: 'search=' + encodeURIComponent(search),
success: function (datas) {
if (datas !== "") {
$('#searchOnAPI').autocomplete(datas);
} else {
document.getElementById('autocomplete-content').innerHTML = '<ul class="autocomplete-content dropdown-content"><li><a class="black-text">{{ siteData('site.search.nodata') }}</a></li></ul>';
}
}
});
}
});
});
</script>
I think the problem comes from here:
The variable datas ...
but I don't understand the error anymore.
success: function (datas) {
if (datas !== "") {
$('#searchOnAPI').autocomplete(datas);
}
the code of the search page:
and call API
<?php
if (isset($_GET['search']) && !empty($_GET['search'])) {
$search = trim(htmlspecialchars($_GET['search']));
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.themoviedb.org/3/search/multi?api_key=". API_KEY ."&language=fr-FR&query=$search",
CURLOPT_CAINFO => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR ."cert.tmdb.cer", //api.themoviedb.org
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 10,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET"
]);
$response = curl_exec($curl);
$err = curl_error($curl);
$response = json_decode($response, true);
$err = json_decode($err, true);
$datas = [];
if (!is_null($err) || $response === null || !isset($response['results'])) {
$datas[] = ['No Data' => null];
} else {
$response = $response['results'];
for ($i = 0; $i <= 5; $i++) {
if (isset($response[$i]['title'])) {
$datas[] = $response[$i]['title'] ;
} elseif (isset($response[$i]['name'])) {
$datas[] = $response[$i]['name'];
}
}
echo json_encode(array_fill_keys(['data'], array_fill_keys($datas, null)), true);
}
}
and here is the api return in json of the search page
{
"data": {
"O Amor Acontece": null,
"Quem Quer Namorar Com o Agricultor?": null,
"O'": null,
"O Clone": null,
"Hawaï police d'État": null,
"O Matador": null
}
}
Any advice is welcome!
.EDD
Your PHP code is returning a json object with a 'data' parameter, maybe you could try
if (datas !== "") {
$('#searchOnAPI').autocomplete(datas.data);
}
I found the error:
$.ajax({
type: 'GET',
url: '/search.php',
data: 'search=' + encodeURIComponent(search),
success: function (datas) {
I did not set the dataType ...
dataType:"json",
like this
$.ajax({
type: 'GET',
dataType:"json",
url: '/search.php',
data: 'search=' + encodeURIComponent(search),
success: function (datas) {
But with everything works.
find on [Jquery autocomplete _renderItem is not working][1]
I've seen and tried a few answers that are similar to this question, but it still displays the same error.
The console is also giving the error: Uncaught TypeError: Cannot read property 'length' of undefined at Function.each (jquery-1.10.2.js:631)
My view:
<form action="https://dev.vmc.w3.uvm.edu/xana/sensors/deployments" class="basicForm aboutForm form-horizontal" id="deploymentForm" enctype="multipart/form-data" method="post" accept-charset="utf-8">
<div class="form-group">
<label for="fldFileName" class="col-sm-4 control-label">Image</label>
<div class="col-sm-8">
<input type="file" name="fldFileName" value="" class="form-control" id="fldFileName" />
</div>
</div>
<button type="button" class="btn btn-primary" id="newSensorSubmit">Save</button>
</form>
javascript to submit form:
$(document).on("click", "#newSensorSubmit", function(event){
var posturl="<?php echo site_url("sensors/add_deployment");?>";
var formData = new FormData();
var fldFileName = $('#fldFileName').val();
formData.append('fldFileName', fldFileName);
jQuery.ajax({
url: posturl,
data: formData,
cache: false,
mimeType: "multipart/form-data",
dataType: 'json',
contentType: false,
processData: false,
type: 'POST',
success: function(data){
if(data.status === 'success') {
//handle success
}
else {
//handle fail
}
},
error: (error) => {
$('#articleErrorText').html(JSON.stringify(error));
}
});
});
controller:
public function add_deployment(){
$this->load->helper(array('form', 'url'));
$this->load->library('upload');
$config = array(
'upload_path' => site_url("attachments/project/999/metstations"),
'allowed_types' => "gif|jpg|png|jpeg",
'overwrite' => TRUE,
'max_size' => "16000000"
);
$this->load->library('upload', $config);
if($this->upload->do_upload('fldFileName'))
{
$data['image_metadata'] = array('image_metadata' => $this->upload->data());
}
else
{
$error = $this->upload->display_errors();
$data['errors']='<p class="error-message">'.$error.'</p>';
$data['status']='failure';
}
}
Try This.
To get all your form inputs, including the type="file" you need to use FormData object.
To append param just use append() method:
formData.append("param", "value");
And in the php-side I catch it:
echo $file_name = ($_FILES['file']['name']);
View Code:-
<body>
<p id="msg"></p>
<input type="file" id="file" name="file" />
<button id="upload">Upload</button>
</body>
jQuery / Ajax Code:-
<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function(e){
$('#upload').on('click', function () {
var file_data = $('#file').prop('files')[0];
var form_data = new FormData();
form_data.append('file', file_data);
$.ajax({
url: 'ControllerName/upload_file', // point to server-side controller method
dataType: 'text', // what to expect back from the server
cache: false,
contentType: false,
processData: false,
data: form_data,
type: 'post',
success: function (response) {
$('#msg').html(response); // display success response from the server
},
error: function (response) {
$('#msg').html(response); // display error response from the server
}
});
});
});
</script>
Controller Code:-
class ControllerName extends CI_Controller {
function __construct() {
parent::__construct();
}
function upload_file() {
//upload file
$config['upload_path'] = 'uploads/';
$config['allowed_types'] = '*';
$config['max_filename'] = '255';
$config['encrypt_name'] = TRUE; // remove it for actual file name.
$config['max_size'] = '1024'; //1 MB
if (isset($_FILES['file']['name'])) {
if (0 < $_FILES['file']['error']) {
echo 'Error during file upload' . $_FILES['file']['error'];
} else {
if (file_exists('uploads/' . $_FILES['file']['name'])) {
echo 'File already exists : uploads/' . $_FILES['file']['name'];
} else {
$this->load->library('upload', $config);
if (!$this->upload->do_upload('file')) {
echo $this->upload->display_errors();
} else {
echo 'File successfully uploaded : uploads/' . $_FILES['file']['name'];
}
}
}
} else {
echo 'Please choose a file';
}
}
}
Note:- For more reference regarding this check this
https://developer.mozilla.org/en-US/docs/Web/API/FormData/append
Can someone please help me with this?
I'm not that versed at JavaScript and I've read the documentation over and over plus reviewed as many posts here as well as googled the problem. I'm not able to get my cropped result and send it to my web server. Here's my code.
HTML:
<form action="" method="post" enctype="multipart/form-data" id="formTest">
<div id="modal">
<div id="main-cropper"></div>
<a class="button actionUpload">
<span>Upload</span>
<input type="file" id="upload" value="Choose Image"
accept="image/*" name="imgf">
</a>
<button class="actionDone">Done</button>
<button class="actionCancel">Cancel</button>
</div>
</form>
JS:
<script>
var basic = $('#main-cropper').croppie({
viewport: { width: 300, height: 400, type: 'square' },
boundary: { width: 700, height: 500 },
showZoomer: true
});
function readFile(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#main-cropper').croppie('bind', {
url: e.target.result
});
$('.actionDone').toggle();
$('.actionUpload').toggle();
}
reader.readAsDataURL(input.files[0]);
}
}
$('.actionUpload input').on('change', function () { readFile(this); });
$('.actionDone').on('click', function(){
$('#main-cropper').croppie('result', {
type: 'canvas',
size: 'viewport'
}).then(function (resp) {
$('#formTest').find('name=["imgf"]').val('src', resp);
});
$('.actionDone').toggle();
$('.actionUpload').toggle();
});
</script>
I did some additional research and found a solution through using AJAX. I tried it and it works. Need to do some clean up on the CSS but that's nothing major. Here is some of the modified code:
partial JavaScript:
$('.crop_image').click(function(event){
image_crop.croppie('result', {
type: 'canvas',
size: 'viewport'
}).then(function(response){
$.ajax({
url:"upload.php",
type: "POST",
data:{"image": response},
success:function(data)
{
$('#uploadimageModal').modal('hide');
$('#uploaded_image').html(data);
}
});
})
});
AJAX:
if(isset($_POST["image"]))
{
$data = $_POST["image"];
$image_array_1 = explode(";", $data);
$image_array_2 = explode(",", $image_array_1[1]);
$data = base64_decode($image_array_2[1]);
$imageName = time() . '.png';
file_put_contents("pg/$imageName", $data);
echo '<img src="'.$imageName.'" class="img-thumbnail" />';
}
https://www.webslesson.info/2018/03/image-crop-and-upload-using-jquery-with-php-ajax.html
I have a few caption boxes that I want to be able to edit inline and to save these to my database to update a certain record in my table.
For some reason, nothing happens when I click the save button.. not even in the console.
It's just using jQuery at the moment, will I have to use AJAX for this?
If so any tips would be great to point me in right direction as I'm not familiar that much with AJAX.
Here is my code:
index.php
<div class="caption" id="caption1" contenteditable="true" style="min-height: 450px;">
<?php
$query3 = "SELECT * From (select * from ckeditor ORDER BY id DESC LIMIT 2) AS name ORDER BY id LIMIT 1";
$show = mysql_query($query3, $con);
while ($row = mysql_fetch_array($show))
{
echo $row['file'];
}
?>
</div>
<button type="button" id="save"><span>Save</span></button>
<script>
$(document).ready(function (e) {
$("#save").click(function (e) {
var data = CKEDITOR.instances.caption1.getData();
var options = {
url: "save.php",
type: "post",
data: { "editor" : encodeUriComponent(data) },
success: function (e) {
echo "Succesfully updated!";
}
};
}
});
</script>
</div>
save.php
<?php
$connection = mysql_connect("localhost", "", "");
$db = mysql_select_db("castle", $connection);
//Fetching Values from URL
$data = nl2br($_POST['caption1']);
//Insert query
$query ="INSERT INTO `ckeditor`(`file`) VALUES ('$data')";
echo "Form Submitted Succesfully";
mysql_close($connection);
?>
You need to send the data to the server like this;
$.ajax({
url: "save.php",
data: {
"editor" : encodeUriComponent(data)
},
error: function() {
//Error
},
success: function(data) {
//Success
},
type: 'POST'
});
Currently you are just creating an object called 'options'
Your code should look like this;
$("#save").click(function (e) {
var data = CKEDITOR.instances.caption1.getData();
$.ajax({
url: "save.php",
data: {
"editor" : encodeUriComponent(data)
},
error: function() {
//Error
},
success: function(data) {
alert('Success');
},
type: 'POST'
});
}
Just a side note, 'echo' doesn't work in js. You need to use 'alert()' or 'console.log()'
I have a problem related with passing two forms in ajax to my controller code igniter. My first form is a file var formData = new FormData($('#form-upload')[0]);
and my second form consists of profile data $('#frm_patientreg').serialize()
now my problem is how can I pass these two forms in ajax?
I already tried this code:
var fileToUpload = inputFile[0].files[0];
if(fileToUpload != 'undefine') {
var formData = new FormData($('#form-upload')[0]);
$.ajax({
type: "POST",
url: siteurl+"sec_myclinic/addpatient",
data: $('#frm_patientreg').serialize()+formData,
processData: false,
contentType: false,
success: function(msg) {
alert("Successfully Added");
$('#frm_patientreg')[0].reset();
}
});
}
else {
alert("No File Selected");
}
but it returns me an error.
When I tried to pass data:formData, only, my image file was successfully uploaded, but when I add the $('#frm_patientreg').serialize(), it outputs an error. How can I pass both forms?
Here is my controller:
public function addpatient() {
$config['upload_path'] = './asset/uploaded_images/';
$config['allowed_types'] = 'gif|jpg|jpeg|png';
$config['max_size'] = 1024 * 8;
$this->load->library('upload', $config);
if($this->upload->do_upload("file")) {
$upload_data = $this->upload->data();
$file_name = base_url().'asset/uploaded_images/'.$upload_data['file_name'];
$mypatiendid = $this->genpatient_id();
$patient_bday = $this->input->post('pabdate');
$DB_date = date('Y-m-d', strtotime($patient_bday));
$patient_height = $this->input->post('paheight');
$DB_height = $patient_height . " cm";
$patient_weight = $this->input->post('paweight');
$DB_weight = $patient_weight . " kg";
$data = array (
'patient_id' => $mypatiendid,
'patient_fname' => $this->input->post('pafname'),
'patient_mname' => $this->input->post('pamname'),
'patient_lname' => $this->input->post('palname'),
'patient_address' => $this->input->post('paaddress'),
'patient_contact_info' => $this->input->post('pacontact'),
'patient_bday' => $DB_date,
'patient_age' => $this->input->post('paage'),
'patient_height' => $DB_height,
'patient_weight' => $DB_weight,
'patient_sex' => $this->input->post('psex'),
'patient_civil_status' => $this->input->post('pmartialstat'),
'patient_photo' => $file_name,
);
var_dump($data);
}
else {
echo "File cannot be uploaded";
$error = array('error' => $this->upload->display_errors()); var_dump($error);
}
}
Not tested..but try this:
var FormTwo = new FormData();
$('#frm_patientreg input, #frm_patientreg select').each(function(index){
FormTwo.append($(this).attr('name'),$(this).val());
});
FormTwo.append('file', $('#frm_patientreg input[type=file]')[0].files[0]);
$.ajax({
type: "POST",
url: siteurl+"sec_myclinic/addpatient",
data: {formTwo: FormTwo, formOne: formData},
processData: false,
contentType: false,
success: function(msg) {
alert("Successfully Added");
$('#frm_patientreg')[0].reset();
}
});
change this
data: $('#frm_patientreg').serialize()+formData,
into this
data: $('#frm_patientreg').serialize()+'&'+formData,