I am practicing on a very simple Laravel project with AJAX and jQuery. I am trying to edit post and its meta information which I added before. I Tried console.log and its showing me post with meta information. Post is coming from posts table and meta information is coming from post_metas table where I added post_id as forign key. Post data is showing in edit modal but I am unable to put meta information in their specific fields in edit Modal.
Here is my PostController.php
public function edit($id)
{
$post = Post::with('meta')->find($id);
if ($post) {
return response()->json([
'status' => 200,
'post' => $post,
]);
} else {
return response()->json([
'status' => 404,
'message' => 'Post Not Found',
]);
}
}
Here is Index.blade.php (jQuery AJAX Code)
$(document).on('click', '.edit_post_btn', function(e) {
e.preventDefault();
var post_id = $(this).val();
var route_url = "{{ route('blog.edit', ':id') }}";
route_url = route_url.replace(':id', post_id);
$.ajax({
type: "GET",
url: route_url,
success: function(response) {
if (response.status === 200) {
console.log(response.post);
$('#edit_title').val(response.post.title);
$('#edit_excerpt').val(response.post.excerpt);
$('#edit_content').val(response.post.content);
$('#edit_min_to_read').val(response.post.min_to_read);
$('#edit_meta_description').val(response.post.meta_description);
$('#edit_meta_keywords').val(response.post.meta_keywords);
$('#edit_meta_robots').val(response.post.meta_robots);
} else {
console.log(response.message);
}
}
});
});
And This is My route:
Route::get('/edit/{id}', [PostController::class, 'edit'])->name('blog.edit');
See File Please:
Meta information is in the meta object:
$('#edit_meta_description').val(response.post.meta.meta_description);
$('#edit_meta_keywords').val(response.post.meta.meta_keywords);
$('#edit_meta_robots').val(response.post.meta.meta_robots);
Related
i want to call route resource with ajax, when i put type as delete i got error (exception "Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException")
and given message (message "The DELETE method is not supported for this route. Supported methods: GET, HEAD, POST.").function almost work beacuse after make refresh the status also change but i am the above error.
route :
Route::resource('category', ArtistCategoryController::class);
controller :
public function destroy($id)
{
$category = ArtistCategory::findOrFail($id);
$deleteResponse = $category->update([
'status'=>'d'
]);
if ($deleteResponse) {
deleteMessage();
return redirect()->back();
} else
errorMessage();
}
view :
</i>
ajax:
<script>
$(".categoryDelete").on('click', function (e) {
e.preventDefault();
let id = $(this).data('id')
// console.log(id)
$.ajax({
url: '/artist/category/'+id,
type: 'DELETE',
data:{"id": id, "_token": "{{ csrf_token() }}"},
success: function (data)
{
alert(data)
},
error: function (e){
alert(e)
}
});
})
</script>
solved it with some changes in destroy method
because i have used return return redirect()->back();it gives error and this is unacceptable
updated
public function destroy($id): \Illuminate\Http\JsonResponse
{
$category = ArtistCategory::findOrFail($id);
$deleteResponse = $category->update([
'status'=>'d'
]);
if ($deleteResponse) {
return response()->json([
'data' => [
'id' => $id
],
'status' => 'success',
]);
} else
{
return response()->json([
'data' => [
'id' => $id
],
'status' => 'error',
'message' => __("Couldn't Delete. Please Try Again!")
], 500);
}
}
You need to set the csrf token in the header. Have a look at the docs in the bottom of the page: https://laravel.com/docs/8.x/csrf#csrf-x-csrf-token
Create a meta tag with the token like this:
<meta name="csrf-token" content="{{ csrf_token() }}">
And grap it like this:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
I'm trying to use select2 retrieving large data in my dropdown using the following article.
Getting 500 Internal Server Error in my console log.
I have store token in HTML meta tag.
<meta name="csrf-token" content="{{ csrf_token() }}">
And sending a token as a parameter in my POST request.
var CSRF_TOKEN = $('meta[name="csrf-token"]').attr('content');
$(document).ready(function(){
$( "#test" ).select2({
ajax: {
url: "path/to/url",
type: "POST",
dataType: 'JSON',
delay: 250,
data: function (params) {
return {
_token: CSRF_TOKEN,
search: params.term // search term
};
},
processResults: function (response) {
return {
results: response
};
},
cache: true
}
});
});
<select class="test" id="test" style="width:100%;"></select>
I have checked routes using php artisan route:list and clear cache using php artisan config:cache. But still getting the same error link. and link.
Is there anything I'm missing? I would be grateful if you can help me out to debug/inspect my Request and Response.
Tried
error: function(err){
console.log(err)
}
Server-Side \ Controller
public function getdata(Request $request){
$search = $request->search;
if($search == ''){
$data = DB::table('table')
->orderby('name','asc')
->select('id','name')
->limit(5)->get();
}else{
$data = DB::table('table')
->orderby('name','asc')
->select('id','name')
->where('name', 'like', '%' .$search . '%')
->limit(5)->get();
}
$response = array();
foreach($data as $i){
$response[] = array(
"id"=>$i->id,
"text"=>$i->name
);
}
return response()->json($response);
}
Happy Coding.
I'm trying to create a new service option while creating a bill (a bill can have many services), it's like creating a new tag, or category while writing post without reloading, but i have this internal server error 500, i think the problem is in the Controller because it works fine when i comment the create in controller, route and csrf and stuff are checked, thanks for helping me !
In my javascript :
var max_service_id = {{$max_service_id}};
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$("#add_service_button").on("click",function(e){
e.preventDefault();
var service_name = $("input[name=service_name]").val();
var service_category = document.getElementById('service_category').value;
var service_description = $("input[name=service_description]").val();
$.ajax({
type:'POST',
url:'/service/add-in-bill',
dataType: 'json',
data:{
name : service_name,
category_id : service_category,
description : service_description
},
success:function(data){
if (data.message) {
//This is error message
alert(data.message);
}
if (data.success) {
alert(data.success);
var newService = new Option(service_name, max_service_id, false, true);
$('.multipleSelect').append(newService).trigger('change');
max_service_id++;
$("#add_service_div").hide("fast");
}
}
});
})
});
In my controller :
$validator = Validator::make($request->all(), [
'name' => 'required|unique:services',
'category_id' => 'required',
]);
if ($validator->fails()) {
return response()->json(['message'=>$validator->errors()->all()]);
} else {
// It works fine when i comment this, so i think the problem is something about variables from javascript to php stuff
Service::create($request->all());
return response()->json(['success'=>'Create service success !']);
}
//
// I think the problem is in the Controller because it works fine when i comment the "Service::create($request->all());"
FilePond.revert does not transfer unique id files to the laravel controller.
How to delete the downloaded file by ID?
FilePond JS
var csrf = $('meta[name="csrf-token"]').attr('content');
FilePond.setOptions({
server: {
url: '/file/upload/',
process: {
url: 'process',
headers: {
'X-CSRF-TOKEN': csrf
},
onload: function (responce) {
console.log(JSON.parse(responce))
},
},
revert: {
url: 'revert',
headers: {
'X-CSRF-TOKEN': csrf
},
onload: function (x) {
// X - empty, why????
console.log(x)
},
},
load: {
url: 'load/',
},
},
})
FilePond.create(document.querySelector('.filepond[type="file"]'), {
files: [
{
source: '11',
options: {
type: 'local',
}
},
]
});
Loading pictures work successfully.
Return unique ID file in response.
public function process(){
$file = FilesUploadService::save();
return response($file->collection->id, 200)
->header('Content-Type', 'text/plain');
}
Empty here I can't find the file id. Which need to be removed
public function revert(Request $request){
return response()->json($request->all());
}
Anyone still struggling:
request->getContent() will return the request payload sent by filepond.
In revert method in controller:
public function revert(Request $request){
$fileId = request()->getContent();
//use $fileId to delete file from filesystem
}
The onload method below should return a unique id to FilePond. So, for example, if the unique id is found in responce.id you add the return line like shown.
onload: function (responce) {
console.log(JSON.parse(responce))
return JSON.parse(responce).id // added
},
Did you get this to work? FilePond uses the DELETE header when reverting, that may be why you're not getting anything from request.
Maybe something like this?
public function revert(){
$response = new stdClass();
if ($_SERVER['REQUEST_METHOD'] === 'DELETE') {
$file_name = strip_tags(file_get_contents("php://input"));
if (is_string($file_name) && FilesUploadService::delete($file_name)) {
$response->id = $file_name;
$response->success = true;
} else {
$response = false;
}
} else {
$response = false;
}
return response()->json($response);
}
I've been struggling with reverting/deleting an early uploaded file using FilePondfor a few hours but after scavenging on there documentation I have figured out a quick hack to get around the situation.
On your JavaScript side you'd be doing something like the following to upload the file via XHRobject:
<script>
const pondElement = document.querySelector('input[type="file"]');
const pond = FilePond.create( pondElement );
FilePond.setOptions({
server: {
url: "{!! route('ajax.uploadFiles') !!}",
process: {
headers: {
'X-CSRF-TOKEN': '{!! csrf_token() !!}'
}
},
}
});
</script>
Now to the tricky part: Reverting/Remove:
<script>
const filepond_root = document.querySelector('.filepond--root');
filepond_root.addEventListener('FilePond:processfilerevert', e => {
$.ajax({
url: "{!! route('ajax.revertFiles') !!}",
type: 'POST',
data: {'_token': '{!! csrf_token() !!}', 'filename': e.detail.file.filename}
})
});
</script>
On your ServerSide (Laravel) it's as easy and straight forward as the following:
public function uploadFiles(Request $request)
{
if ($request->has('attachments')) {
if (!file_exists(storage_path('app/tmp'))) {
mkdir(storage_path('app/tmp', 0777, true));
}
$file = $request->file('attachments')[0];
$file_name = $file->getClientOriginalName();
$file_path = storage_path("app/tmp/{$file_name}");
$file->storeAs(null, $file_name, 'tmp');
}
}
public function revertFiles(Request $request)
{
unlink(storage_path("app/tmp/{$request->filename}"));
}
PS: This code is just for demo purposes, please secure your forms and provide a better user experience.
Filepond script at Laravel blade file
<!-- filepond script -->
<script>
const inputElement = document.querySelector('input[id="file"]');
const pond = FilePond.create( inputElement );
FilePond.setOptions({
server: {
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
},
process: {
url: '{{ route('store') }}',
},
revert: {
url: '{{ route('destroy') }}',
}
}
});
</script>
Destroy method at Laravel Controller file
public function destroy(Request $request)
{
$folder = json_decode($request->getContent()); // folder name
}
i have faced the exact same problem. i did 2 thing to fix it.
must have the process.onload function and return the object Id/path. this Id/path will automatically pass to revert function.
in the controller method which handle the revert call. the Id/path from step 1, can be obtain from calling $request->getContent(), notice that $request->all() can not grab the value.
Problem: How do I validate the form and return the validation messages in modal box without refreshing the page.
I just started learning Symfony 3 and I got trouble adding data using AJAX.
I know how to include the template form inside of the modal box but I don't know how to show the error messages of $form->isValid() inside the modal and persist it.
new.html.twig
UPDATE: I can now call the method action in Controller. But when I validate the form I haven't received any validation error inside modal box.
<script>
$(function () {
$('.withdropdown').dropdown();
$('.add-company-launch').modal();
$('#company-form').submit(function(e) {
var formUrl = "{{ path('monteal_backend_company_ajax') }}";
var formData = new FormData(this)
$.ajax({
url: formUrl,
type: 'POST',
data: formData,
contentType: false,
cache: false,
processData: false,
success: function(data, textStatus, jqXHR)
{
if(data['status'] === 'success'){
alert('success');
} else {
$('#add-company').html(data['html']);
}
},
error: function(jqXHR, textStatus, errorThrown)
{
}
});
e.preventDefault();
});
})
</script>
{% endblock %}
CompanyController.php
UPDATE: I have create two methods for AJAX,
1. Method to handle a form.
2. AjaxHandler.
public function newAction() {
$company = new Company();
$form = $this->createForm(CompanyForm::class, $company);
return $this->render('Admin/Backend/Company/new.html.twig', array(
'form'=>$form->createView()
));
}
public function ajaxAction(Request $request) {
if (!$request->isXmlHttpRequest()) {
return new JsonResponse(array('message' => 'You can access this only using Ajax!'), 400);
}
$company = new Company();
$form = $this->createForm(CompanyForm::class, $company);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($company);
$em->flush();
return new JsonResponse(array(
'status' => 'success'), 200
);
}
$html = $this->renderView("Admin/Backend/Company/new.html.twig", array(
'form' => $form->createView())
);
return new JsonResponse(['status' => 'error', 'html' => $html]);
}
1 - In your newAction, just create the form and pass the view (createView) to your template.
2 - write a ajaxFormHandlerAction and here create the form, handle it, validate it, render a view in a variable :
$html = $this->renderView('yourTemplate.html.twig', array($form->createView()));
Edit: of course your ajax must post the form to your newly ajax url... END Edit
3 - if it is'nt validated
Return a JsonResponse(array('html' => $html, 'status' => 'error'));
if validated
Return a JsonResponse(array('status' => 'success'));
4 - In your ajax success callback, render the newly form if status error..
if status success, redirect or whatever
Hope this help
Edit :
something like this for your controler :
use Symfony\Component\HttpFoundation\JsonResponse;
public function ajaxFormHandlerAction(Request $request)
{
$company = getYourCompany(); //get it from db?
$form = $this->createForm(CompanyForm::class, $company));
$form ->handleRequest($request);
if($form ->isValid()){
//do whatever you want, maybe persist, flush()
return new JsonResponse(array(
'status' => 'success'));
}
$html = $this->renderView("yourModalTemplate.html.twig", array('form' => $form->createView()));
return new JsonResponse(['status' => 'error', 'html' => $html]);
}
And in your success ajax callback:
success: function(data, textStatus, jqXHR)
{
if(data['status'] === 'success'){
alert('success');
// maybe redirect the user ???
}else if(data['status' === 'error']){
$('#idOfYourModal').html(data['html']); //assuming you use jquery, or translate to javascript
}
},
You have to create a twig template with only the modal inside...