Laravel AJAX Image Upload error: Image source not readable - php

Trying to upload an image via AJAX but having issues...
The form:
{{ Form::open(array('class' => 'update-insertimage-form', "files" => true,)) }}
{{ Form::file('image', array('class' => 'update-insertimage-btn', 'name' => 'update-insertimage-btn')) }}
{{ Form::close() }}
And the PHP:
$createImage = Image::make(Input::file('update-insertimage-btn'))->orientate();
$createImage->resize(600, null, function ($constraint) {
$constraint->aspectRatio();
});
$createImage->save("user_uploads/cover_images/TEST.jpeg");
jQuery:
$('.update-insertimage-form').submit(function() {
$(".submit-newupdate-btn").addClass('disabled');
var rootAsset = $('.rootAsset').html();
$.ajax({
url: rootAsset+'saveUploadedImage',
type: 'post',
cache: false,
dataType: 'json',
data: $('.update-insertimage-form').serialize(),
beforeSend: function() {
},
success: function(data) {
if(data.errors) {
$('.modal-body').append('<div class="alert alert-danger centre-text modal-error-message" role="alert"><strong>Error!</strong> '+ data.errors +'</div>');
} else if (data.success) {
$(".form-control-addupdate").append(data.name);
}
},
error: function(xhr, textStatus, thrownError) {
alert('Something went to wrong.Please Try again later...');
}
});
return false;
});
I use this same exact code else where which works fine but not with AJAX (not sure if that has anything to do with it)
The error is this:
{"error":{"type":"Intervention\\Image\\Exception\\NotReadableException","message":"Image source not readable","file":"\/Applications\/MAMP\/htdocs\/buildsanctuary\/vendor\/intervention\/image\/src\/Intervention\/Image\/AbstractDecoder.php","line":257}}
Any help?

You can't serialize the image and pass it over, you need to construct a FormData object and use it to send over the image.
var formData = new FormData();
formData.append('update-insertimage-btn[]', $('.update-insertimage-btn')[0].files[0], $('.update-insertimage-btn')[0].files[0].name);
Then you just need to pass it over to the server as the data along with some other options:
data: formData,
processData: false,
contentType: false
Now you can do:
Image::make(Input::file('update-insertimage-btn'))->orientate()
From the page here https://github.com/Intervention/image/blob/master/src/Intervention/Image/AbstractDecoder.php it is passing this following check:
case $this->isDataUrl():
return $this->initFromBinary($this->decodeDataUrl($this->data));
Which is returning true from that function:
public function isDataUrl()
{
$data = $this->decodeDataUrl($this->data);
return is_null($data) ? false : true;
}
which is firing the abstract function initFromBinary that is passing decodeDataUrl's result as an argument, and the decodeDataUrl looks like:
private function decodeDataUrl($data_url)
{
$pattern = "/^data:(?:image\/[a-zA-Z\-\.]+)(?:charset=\".+\")?;base64,(?P<data>.+)$/";
preg_match($pattern, $data_url, $matches);
if (is_array($matches) && array_key_exists('data', $matches)) {
return base64_decode($matches['data']);
}
return null;
}
So it seems it expects that element to be a base64 encoded image as opposed to a raw binary image; therefore, base64encode the image when you pass it along instead of passing along .files[0]

Related

DELETE not working in the Laravel Datatable

I am working with Laravel Datatable and I have stuck in one point. Below code for delete the entry in the TagManagement model. But it isn't delete the entry and worse thing is it didn't show any error. Can anybody find the error in below code?
view
$(document.body).on("click",".remove-tag", function () {
var tag_id = $(this).data('id');
showConfirm("DELETE", "Do you want to delete this Tag ?","deleteTag("+tag_id+")");
});
function deleteTag(id){
$.ajax({
type: 'get',
url: '{!! url('delete-tag') !!}',
data: {tag_id: id},
success: function (data) {
if (data == "SUCCESS") {
$('[data-id="' + id + '"]').closest('tr').remove();
showAlert("SUCCESS","Delete Tag successful");
}
}, error: function (data) {
showAlert("FAIL","Delete Tag fail");
}
});
}
var tag_id = $(this).data('id');
showConfirm("DELETE", "Do you want to delete this Tag ?","deleteTag("+tag_id+")");
});
function deleteTag(id){
$.ajax({
type: 'get',
url: '{!! url('delete-tag') !!}',
data: {tag_id: id},
success: function (data) {
if (data == "SUCCESS") {
$('[data-id="' + id + '"]').closest('tr').remove();
showAlert("SUCCESS","Delete Tag successful");
}
}, error: function (data) {
showAlert("FAIL","Delete Tag fail");
}
});
}
Controller
public function destroy($id)
{
$tagManagement = TagManagement::find($id);
$deleted = $tagManagement->delete();
if ($deleted) {
return "SUCCESS";
} else {
return "FAIL";
}
}
public function loadTags()
{
$Tags = TagManagement::all();
return DataTables::of($Tags)
->addColumn('action', function ($tag) {
return '<i class="fa fa-wrench" aria-hidden="true"></i>
<button type="button" data-id="' . $tag->id . '" class="btn btn-default remove-tag remove-btn" data-toggle="tooltip" data-placement="top" title="Delete"><i class="fas fa-trash-alt" aria-hidden="true"></i></button>';
})
->rawColumns(['action'])
->make(true);
}
}
**Route**
Route::get('/delete-tag', 'AdminPanel\TagController#destroy');
Your route and controller method don't seem to correspond. First of all, it is better to use the "delete" HTTP request method for delete actions, but this is not what is causing your problem.
You defined your route as /delete-tag but in your controller you expect an $id as a parameter to your destroy method. In order for that to work you would need to have the route like this /delete-tag/{id} and construct the URL for your ajax call correspondingly on the frontend. I'm surprised you don't get the Missing argument 1 for App\Providers\RouteServiceProvider::{closure}() exception for malforming your request this way.
Laravel documentation explains very well how to define routes with parameters.
It would be helpful if you included Laravel version in your question.
Here is how it should work:
Route definition
Route::delete('/delete-tag/{id}', 'AdminPanel\TagController#destroy')->name('delete-tag');
JS function
function deleteTag(id){
let route = '{!! route('delete-tag', ['id' => '%id%']) !!}';
$.ajax({
type: 'post',
url: route.replace('%id%', id);,
data: {_method: 'delete'},
success: function (data) {
if (data == "SUCCESS") {
$('[data-id="' + id + '"]').closest('tr').remove();
showAlert("SUCCESS","Delete Tag successful");
}
}, error: function (data) {
showAlert("FAIL","Delete Tag fail");
}
});
}
It is not your Datatable problem, you missed some code, you did not define route & jQuery function properly, your destroy($id) function received a parameter but you do not receive any parameter in your route & you not send _token in your ajax action you need to send _token
Check My code I am edited your code.
//Change your Route
Route::get('delete-tag/{id}', 'AdminPanel\TagController#destroy')->name('deleteTag');
//Change your function
function deleteTag(id){
$.ajax({
type: "GET",
dataType: 'JSON',
url:'{{ route('deleteTag', '') }}/'+id,
data: {_token: '{{csrf_token()}}'},
success: function (data) {
if (data == "SUCCESS") {
$('[data-id="' + id + '"]').closest('tr').remove();
showAlert("SUCCESS","Delete Tag successful");
}
}, error: function (data) {
showAlert("FAIL","Delete Tag fail");
}
});
}

Rendering view after changing Locale by Ajax in Symfony 4

I am trying to change page language by a dropdown. Dropdown is generated by this code {{ form_widget(registrationForm.locale, { 'attr': {'onChange': 'languageChange()'} }) }} in the twig.
Ajax function
function languageChange() {
let selectedLanguage = $('#email_form_locale').val();
$.ajax({
url: '{{ path('change_locale') }}',
type: 'POST',
dataType: 'json',
data: {'selectedLanguage': selectedLanguage},
async: true,
success: function(data, status) {
console.info(data);
location.reload();
},
error : function(xhr, textStatus, errorThrown) {
alert('Ajax request failed.');
}
});
}
Controller function
/**
* #Route("/registration/changeLocale", name="change_locale")
* Method({"GET","POST"})
*/
public function changeLocale (Request $request)
{
$user = new User();
$form = $this->createForm(EmailFormType::class, $user);
if ($request->isXmlHttpRequest()) {
$jsonData = array();
$temp = $request->request->all();
$jsonData[0] = $temp;
$request->getSession()->set('_locale', $temp['selectedLanguage']);
$request->setLocale($temp['selectedLanguage']);
$jsonData[1] = $request->getLocale();
$user->setLocale($temp['selectedLanguage']);
return new JsonResponse(array(
'jsonData' => $jsonData,
'html' => $this->renderView('main/registration.html.twig', array('registrationForm' => $form->createView()))
)
);
} else {
return $this->render('main/registration.html.twig');
}
I am trying to render the view after Jason response. Then the page must be selected languge( I have added the translation module and words for certain languages in translation folder and If I change the locale in services.yaml languages are changing)
Please help me to do this.
I guess that's what you look for ?
https://symfony.com/doc/current/translation/locale.html
If you follow what's explained here, it should set the Locale for the whole Translation component during that request. So all your translated labels will change.

set name to widget's attribute in Twig

I have a field (called name), Every time i write in this field, an ajax script (live search sends data from twig to the controller without reloading) checks if the data already exist or not showing a message. My problem is that i could't set a name for this field, i tried this but it does not work
{{ form_label(form.name) }}
{{ form_widget(form.name,{'id':'name','attr':{'name':'name'}}) }}
{{ form_errors(form.name) }}
and here my function in the controller which i'm sure it works properly,
public function searchBackTeamAction(Request $request)
{
if($request->isXmlHttpRequest())
{
$serializer = new Serializer(array(new ObjectNormalizer()));
$em = $this->getDoctrine()->getManager();
$teams= $em->getRepository('TeamBundle:Team')->findOneBy(['name'=>$request->get('name') ]);
$data = $serializer->normalize($teams);
return new JsonResponse($data);
}
}
and here is my script i'm also sure that it works properly
<script>
$(document).ready(function () {
$("#name").keyup(
function(){
$.ajax({
url: "{{ path('team_searchBack') }}",
data: $("#name").serialize(),
type:"POST",
success: function (data, status, object) {
console.log(data);
if(data.name != null)
{
$("#error_login").css('display','block');
$("#submit").prop('disabled', true);
}
else
{
$("#error_login").css('display','none');
$("#submit").prop('disabled', false);
}
},
error: function(req, textStatus, errorThrown,data) {
//this is going to happen when you send something different from a 200 OK HTTP
console.log('Ooops, something happened: ' + textStatus + ' ' +errorThrown);
},
complete: function() {
// Runs at the end (after success or error) and always runs
}
});
})
}
);
</script>
Could you please help me ?
Use following javascript
<script>
$(document).ready(function () {
$("#name").keyup(
function(){
$.ajax({
url: "{{ path('team_searchBack') }}",
data: {"name": $("#name").val()},
type:"POST",
success: function (data, status, object) {
console.log(data);
if(data.name != null)
{
$("#error_login").css('display','block');
$("#submit").prop('disabled', true);
}
else
{
$("#error_login").css('display','none');
$("#submit").prop('disabled', false);
}
},
error: function(req, textStatus, errorThrown,data) {
//this is going to happen when you send something different from a 200 OK HTTP
console.log('Ooops, something happened: ' + textStatus + ' ' +errorThrown);
},
complete: function() {
// Runs at the end (after success or error) and always runs
}
});
})
}
);

Pass a View Data From Controller to Ajax View File - Laravel 5

From View Page I am calling Ajax to my Controller, from my Controller I want to create a html data so I am passing my array to View file to create a HTML data.
I don't know why when I try to do console nothing gets return, can anyone tell me where I am going wrong
CallingAjaxFromViewFile
function AjaxgetCheckInChekOutUser(status){
var url = "{{ url('admin/events/ajaxData') }}";
var token = $('#token').val();
if(status){
$.ajax({
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
},
url: url,
type: 'POST',
data: {'status': status,'_token':token},
success: function (data) {
alert(data);
data = JSON.parse(data);
console.log(data.html);
$('#gymimages').html(data.html);
}
});
}
}
myControllerFile
public function AjaxCurrentPastFutureData($data, $status){
$title = "HDTuto.com";
$html = view('admin.events.ajaxdataview')->with(compact('title'))->render();
//pr($html);
$response = response()->json(['success' => true, 'html' => $html]);
return $response;
}
NowmyViewFile From Where I append HTML Data
<h1><i>{{ $title }} </i></h1>
Can anyone tell me where I am going wrong?
** Use this**
function AjaxgetCheckInChekOutUser(status){
var url = "{{ url('admin/events/ajaxData') }}";
var token = $('#token').val();
if(status){
$.ajax({
url: url,
type: 'POST',
data: {'status': status,'_token':token},
success: function (data) {
$('#gymimages').html(data.html);
}
});
Also update your Controller function
public function AjaxCurrentPastFutureData(Request $request){
$title = "HDTuto.com";
$html = view('my')->with(compact('title'))->render();
//pr($html);
$response = response()->json(['success' => true, 'html' => $html]);
return $response;
}

Codeigniter, Ajax: Pass html string from view to controller

I'm trying to pass a long Html string from a view to a controller using an ajax call, so I can pass it further to another view.
Markup:
<a id="openPDF">Save as PDF</a>
JS:
$('#openPDF').click(function(){
var htmlText = $( "div.modal" ).html(); //grab the html
var dataToSend = JSON.stringify("{strData : '" + htmlText + "' }");
console.log(dataToSend ); // contains the json
$.ajax({
url: "/dashboard/pdf",
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: dataToSend
success: function (msg) { alert(msg.d); },
error: function (type) { alert("ERROR!" + type.responseText); }
});
});
Controller:
public function pdf(){
$data['htmlString'] = json_decode($this->input->post('strData'));
$this->load->view('pdf', $data);
}
My ajax call doesn't work because when a click the #openPDF button i get the alert error:
ERROR! NULL
What am I doing wrong?
Are you setting your headers properly before writing the output?
Controller:
public function pdf() {
$data['htmlString'] = json_decode($this->input->post('strData'));
$viewString = $this->load->view('pdf', $data, true); // this returns view as string rather than outputting it
header('Content-Type: application/json');
echo json_encode(['viewString' => $viewString]);
}
In client-side js, you can pass this success function to $.ajax()
success: function (response) {
if ('undefined' !== typeof response.viewString) {
// append view to concerned element
$('#viewTarget').append(response.viewString);
} else {
console.log('response did not contain viewString');
}
},
I hope this helps.
Also:
Navigate directly to the url (the one you are sending an ajax request for) in your browser and see if you get a valid json output.

Categories