How to update image with AJAX in Laravel - javascript

I'm having problems updating a record with an image. I don't what I need to do. My image is stored in a public folder called 'img/products'
ProductController.php
This is my controller. It works well without modifying the image.
public function update(Request $request, $id)
{
$validator = Validator::make($request->input(), array(
'name' => 'required',
'category_id' => 'required',
'description' => 'required',
'price_neto' => 'required',
'iva' => 'required',
'price_total' => 'required',
'image' => '',
));
if ($validator->fails()) {
return response()->json([
'error' => true,
'messages' => $validator->errors(),
], 422);
}
$products = Product::find($id);
$products->name = $request->input('name');
$products->category_id = $request->input('category_id');
$products->description = $request->input('description');
$products->price_neto = $request->input('price_neto');
$products->iva = $request->input('iva');
$products->price_total = $request->input('price_total');
$products->image = $request->input('image');
$products->save();
return response()->json([
'error' => false,
'products' => $products,
], 200);
}
Product.js
All I know is that I have to use var formData = new FormData ($ ("# frmAddProduct") [0]); as in the store function. I can enter records with images but not edit them. My image is stored in a public folder called 'img/products'
$(document).ready(function() {
$("#btn-edit").click(function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
type: 'PUT',
url: '/product/' + $("#frmEditProduct input[name=product_id]").val(),
data: {
name: $("#frmEditProduct input[name=name]").val(),
category_id: $("#frmEditProduct select[name=category_id]").val(),
description: $("#frmEditProduct input[name=description]").val(),
price_neto: $("#frmEditProduct input[name=price_neto2]").val(),
iva: $("#frmEditProduct input[name=iva2]").val(),
price_total: $("#frmEditProduct input[name=price_total2]").val(),
image: $("#frmEditProduct input[name=image]").val(),
},
dataType: 'json',
success: function(data) {
$('#frmEditProduct').trigger("reset");
$("#frmEditProduct .close").click();
window.location.reload();
},
error: function(data) {
var errors = $.parseJSON(data.responseText);
$('#edit-product-errors').html('');
$.each(errors.messages, function(key, value) {
$('#edit-product-errors').append('<li>' + value + '</li>');
});
$("#edit-error-bag").show();
}
});
});
});
function editProductForm(product_id) {
$.ajax({
type: 'GET',
url: '/product/' + product_id,
success: function(data) {
$("#edit-error-bag").hide();
$("#frmEditProduct input[name=name]").val(data.products.name);
$("#frmEditProduct select[name=category_id]").val(data.products.category_id);
$("#frmEditProduct input[name=description]").val(data.products.description);
$("#frmEditProduct input[name=price_neto2]").val(data.products.price_neto);
$("#frmEditProduct input[name=iva2]").val(data.products.iva);
$("#frmEditProduct input[name=price_total2]").val(data.products.price_total);
$("#frmEditProduct file[name=image]").val(data.products.image);
$("#frmEditProduct input[name=product_id]").val(data.products.id);
$('#editProductModal').modal('show');
},
error: function(data) {
console.log(data);
}
});
}

You should check if the file exists before trying to delete, for example:
$product = Product::find($id);
if(!$product)
{
return response()->json(['error' => 'Product not found'], 404);
}
if (Storage::disk('local')->exists('img/products/'.$product->image)) {
Storage::disk('local')->delete('img/products/'.$product->image);
}
Take a look one example only:
public function update(UpdateProductFormRequest $request, $id)
{
$product = Product::find($id);
$data = $request->only('name','category_id','description',
'price_neto','iva','price_total');
if(!$product)
{
return response()->json(['error' => 'Product not found'], 404);
}
// when saving the file, delete the old file first
if ($request->hasFile('image')) {
$file = $request->file('image');
$original_filename = $file->getClientOriginalName();
// $mime = $file->getMimeType(); // Suggestion
$extention = $file->getExtension();
// $size = $file->getClientSize(); // Suggestion
$stored_filename = $original_filename; // md5($original_filename); // Suggestion
$file_path = storage_path('public/img/products/');
if (Storage::disk('local')
->exists("public/img/products/{$stored_filename}.{$extention}"))
{
Storage::disk('local')
->delete("public/img/products/{$recordSet->stored_filename}.{$extention}");
}
$file_moved = $file->move($file_path, "{$stored_filename}.{$extention}");
$data->image = "{$stored_filename}.{$extention}";
}
// Updating data
$result = $product->update($data);
if ($result) {
/* return redirect()
->route('products.index')
->withSuccess('Product was successfully updated'); */
return response()->json([
'message' => 'Product was successfully updated'
'product' => $product
]); // You don't have to put 200 because it's the default
}
/* return back()
->withErrors(['Unable to update the product'])
->withInput($request->input()); */
return response()->json(['error' => 'Unable to update the product'], 400);
}
It would be better if you create a form request to do your validations.
Don't forget to create links to the storage path:
php artisan storage:link
I think it would be helpful:
$("#btn-edit").click(function() {
var formData = new FormData($("#frmAddProduct")[0]);
formData.append('_method', 'put');
formData.append('_token', "{{ csrf_token() }}"); // if you are using Blade
var route= "{{ route('products.update', ['id' => ':id']) }}"; // if you are using Blade
route= route.replace(':id', $("#frmEditProduct input[name=product_id]").val())
$.ajax({
method: 'post',
url: route,
data: formData,
dataType: 'json',
success: function(data) {
$('#frmEditProduct').trigger("reset");
$("#frmEditProduct .close").click();
window.location.reload();
},
error: function(data) {
var errors = $.parseJSON(data.responseText);
$('#edit-product-errors').html('');
$.each(errors.messages, function(key, value) {
$('#edit-product-errors').append('<li>' + value + '</li>');
});
$("#edit-error-bag").show();
}
});
});
Is your js script in "Blade" ? If so, try it this way:
var image = '{{ asset("/img/products/_image_file") }}'
image.replace('_image_file', data.products.image)
$("#frmEditProduct file[name=image]").val(image)
Note that we can first use the "asset ()" helper to create the full path to use to find the image, but with a "_image_file" placeholder
After that, we use the replace () function to change the "_image_file" placeholder with the actual image file brought from the ajax response.

Something like this?
ProductController.php
public function update(Request $request, $id)
{
$validator = Validator::make($request->input(), array(
'name' => 'required',
'category_id' => 'required',
'description' => 'required',
'price_neto' => 'required',
'iva' => 'required',
'price_total' => 'required',
'image' => '',
));
if ($validator->fails()) {
return response()->json([
'error' => true,
'messages' => $validator->errors(),
], 422);
}
$products = Product::find($id);
if ($request->hasFile('image')) {
$productImage = $request->file('image');
$productImageName = rand() . '.' . $productImage->getClientOriginalExtension();
if (Storage::disk('local')->exists("img/products/{$productImageName}")) {
Storage::disk('local')->delete("img/products/{$recordSet->$productImageName}");
}
$file_moved = $productImage->move(public_path('img/products'), $productImageName);
$data->image = "{$productImageName}";
}
$products->save([
'name' => $request->name,
'category_id' => $request->category_id,
'description' => $request->description,
'price_neto' => $request->price_neto,
'iva' => $request->iva,
'price_total' => $request->price_total,
'image' => $productImageName,
]);
return response()->json([
'error' => false,
'products' => $products,
]);
}
Product.js
$("#btn-edit").click(function() {
var formData = new FormData($("#frmEditProduct")[0]);
formData.append('_method', 'put');
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
type: 'POST',
url: '/product/' + $("#frmEditProduct input[name=product_id]").val(),
data: formData,
dataType: 'json',
success: function(data) {
$('#frmEditProduct').trigger("reset");
$("#frmEditProduct .close").click();
window.location.reload();
},
error: function(data) {
var errors = $.parseJSON(data.responseText);
$('#edit-product-errors').html('');
$.each(errors.messages, function(key, value) {
$('#edit-product-errors').append('<li>' + value + '</li>');
});
$("#edit-error-bag").show();
}
});
});

Related

How to refresh fullcalendar using native javascript

I'm using fullcalendar library.
I'm not using query with this library but native javascript. I'm able to create and delete events. But when I do I have to refresh to get it to show. I would like for the calendar to automatically refresh after an event is created or deleted.
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
let model = document.getElementById('my-modal');
var calendar = new FullCalendar.Calendar(calendarEl, {
timeZone: 'UTC',
initialView: 'timeGridWeek',
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay'
},
editable: true,
selectable: true,
events: {!! $data !!},
select: function(event) {
let _token = "{{ csrf_token() }}";
let data = {
'title': 'Event 1',
'start': event.startStr,
'end': event.endStr,
};
fetch("{{ route('booking.calendar.create') }}", {
method: 'post',
data: data,
headers: {
'X-CSRF-TOKEN': _token,
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then(response => response.json())
.then(data => console.log(data));
},
eventChange: function(e) {
let _token = "{{ csrf_token() }}";
let data = {
'title': 'Event 1',
'start':e.event.start,
'end': e.event.end,
};
fetch("http://hair_booking.test/booking/update/" + e.event.id, {
method: 'post',
headers: {
'X-CSRF-TOKEN': _token,
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then(response => response.json())
.then(data => {
})
.catch(function (error){
console.log(error);
})
},
eventClick: function(e) {
e.preventDefault;
var event = confirm('Do you want to delete this event');
if(event) {
let _token = "{{ csrf_token() }}";
let data = {
'title': 'Event 1',
'start':e.event.start,
'end': e.event.end,
};
fetch('http://hair_booking.test/booking/delete/' + e.event.id, {
method: 'DELETE',
headers: {
'X-CSRF-TOKEN': _token,
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then(response => {
response.json()
})
.then(data => data)
.catch(error => {
console.error(error);
});
}
}
});
calendar.render();
});
Here's my laravel route file
Route::middleware(['auth'])->group(function() {
Route::get('/booking', [HairBooking::class, 'render'])->name('booking.calendar');
Route::post('/booking/create', [HairBooking::class, 'create'])->name('booking.calendar.create');
Route::post('/booking/update/{id}', [HairBooking::class, 'updateEvent'])->name('booking.calendar.update');
Route::delete('/booking/delete/{id}', [HairBooking::class, 'deleteEvent'])->name('booking.calendar.delete');
});
Here's my Component blade file to populate the events.
<?php
namespace App\Http\Livewire;
use App\Models\Booking;
use Carbon\CarbonImmutable;
use Livewire\Component;
use Illuminate\Http\Request;
class HairBooking extends Component
{
public function create(Request $request) {
$booking = new Booking();
$booking->title= 'Event 1';
$booking->user_id = auth()->user()->id;
$booking->start = $request->input('start');
$booking->end = $request->input('end');
$booking->save();
return $booking;
}
public function updateEvent(Request $request, $id) {
$event = Booking::find($id);
$event->start = $request->input('start');
$event->end = $request->input('end');
$event->save();
return $event;
}
public function deleteEvent(Request $request, $id) {
$event = Booking::find($id);
$event->delete();
return response()->json(null, 204);
}
public function render()
{
$data = Booking::all()->toJson();
return view('livewire.hair-booking', [
'data' => $data
]);
}
}
And here's my model really bare model.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Booking extends Model
{
use HasFactory;
protected $fillable = [
'user_id',
'title',
'start',
'end',
'allDay'
];
protected $guarded = [];
protected $casts = [
'start' => 'datetime',
'end' => 'datetime'
];
public function user() {
return $this->belongsTo(User::class);
}
}
Any help would be appreciated.

Where is the error: Java Script code

Aplication is built on Yii2 with using Kartik's star-rating widget. Js code have an error:
Image with error in console:
Code:
<?php
$js = <<<JS
function (event, value, caption) {
$.ajax({
type: 'GET',
url: '/rating/update-rating',
data: {
points: value,
post_id: $post->id
},
success: function(res) {
$(event.currentTarget).rating('update', res);
},
error: function(e) {
console.log(e);
}
});
}
JS;
$this->registerJs($js);
echo StarRating::widget([
'name' => $post->post_rate,
'value' => isset($post->rating[0]['dec_avg']) ? $post->rating[0]['dec_avg'] : 0,
'pluginOptions' => [ ... ]
'pluginEvents' => [
'rating:change' => $js,
],
You forgot to add a name for your js function:
function functionName(event, value, caption) {
$.ajax({
type: 'GET',
url: '/rating/update-rating',
data: {
points: value,
post_id: $post - > id
},
success: function(res) {
$(event.currentTarget).rating('update', res);
},
error: function(e) {
console.log(e);
}
});
}

my data not update in the database in laravel 5.4

I am using laravel 5.4 in my app I update some record through ajax jquery I get the data from form values through ajax function and append it in array and pass that array (formData in my code) to ajax data then when I request my data in controller it updated as null message in my database.
This is my view jquery function
$('#updateProduct').on('submit', function(e){
e.preventDefault(e);
var redirect_url = $(this).find("[name='redirect_url']").val();
var url = $(this).attr('action');
var method = $(this).attr('method');
var video = document.getElementById('videoToUpload').files[0];
// console.log(video);
var formData = new FormData();
formData.append('_method', 'patch');
formData.append('name', $(this).find("[name='name']").val());
formData.append('description', $(this).find("[name='description']").val());
formData.append('brand', $(this).find("[name='brand']").val());
formData.append('category', $(this).find("[name='category']").val());
formData.append('condition', $(this).find("[name='condition']").val());
formData.append('shipper', $(this).find("[name='shipper']").val());
formData.append('shipping_from', $(this).find("[name='shipping_from']").val());
formData.append('shipping_paid_by', $(this).find("[name='shipping_paid_by']").val());
formData.append('shipping_within', $(this).find("[name='shipping_within']").val());
formData.append('shipping_weight', $(this).find("[name='shipping_weight']").val());
formData.append('shipping_fee', $(this).find("[name='shipping_fee']").val());
formData.append('seller_get', $(this).find("[name='seller_get']").val());
formData.append('price_per_unit', $(this).find("[name='price_per_unit']").val());
formData.append('selling_fee', $(this).find("[name='selling_fee']").val());
formData.append('seller_id', $(this).find("[name='seller_id']").val());
formData.append('is_active', $(this).find("[name='is_active']:checked").val());
console.log(formData);
$.ajax({
type: method,
url: url,
dataType: 'JSON',
data: formData,
contentType: false,
processData: false,
success: function(data){
alert("Products updated successfullly");
console.log(data);
//window.location.href = redirect_url;
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(JSON.stringify(jqXHR));
console.log("AJAX error: " + textStatus + ' : ' + errorThrown);
}
});
In my controller
public function update(Request $request, $id)
{
return Response::json([
'message' => $request['name']
], 200);
if(!$request){
return Response::json([
'error' => [
'message' => 'Kindly provide all the required details'
]
], 422);
}
$product = Product::find($id);
$product->name = $request['name'];
$product->sku = $request['sku'];
$product->slug = $request['slug'];
$product->description = $request['description'];
$product->brand = $request['brand'];
$product->condition = $request['condition'];
$product->shipper = $request['shipper'];
$product->shipping_from = $request['shipping_from'];
$product->shipping_fee = $request['shipping_fee'];
$product->shipping_paid_by = $request['shipping_paid_by'];
$product->shipping_within = $request['shipping_within'];
$product->shipping_weight = $request['shipping_weight'];
$product->selling_fee = $request['selling_fee'];
$product->seller_get = $request['seller_get'];
$product->price_per_unit = $request['price_per_unit'];
///$product->seller_id = $request['seller_id'];
$product->is_active = $request['is_active'];
$product->save();
$category = ProductCategory::where('product_id', '=', $id);
$category->update([
'category_id' => $request['category']
]);
return Response::json([
'message' => $product
], 200);
}

Jquery Ajax not working on server but working on localhost

I have the following jquery code that posts data to a php file and works fine on localhost. But when this code is now on the server the script returns an error instead of data.
$.ajax({
type: 'POST',
url: 'scripts/info.php',
data: {
accountNumber: accountNumber,
agentName: name
},
success: function( data ) {
alert(data)
},
error: function(xhr, status, error) {
// check status && error
alert(status)
}
});
This is the code in the php file that handles the post request:
$args0 = array(
'accountNumber' => $_POST['accountNumber'],
'dateReceived' => date("Y-m-d"),
'firstNames' => $_POST['agentName'] '
'regNumber' => $_POST['accountNumber'],
'surname' => $_POST['agentName']
);
try {
$client = new SoapClient(WSDL_URL, array(
'trace' => 1,
'exceptions' => true,
'connection_timeout' => 300));
$params = array(
'arg0' => $args0,
);
$client->__setLocation(WSDL_LOCATION);
$response = $client->upload($params);
$response = $client->__getLastResponse();
echo $response;
Please help
$.ajax({
type:"post",
url:"/pay/index.php?submit_order=yes",
dataType:'json',
data:{
'rmb': $('#rmb').val(),
'couponid': $('#cid').val(),
'title' :$('#title').text(),
'user' :$('#user').text(),
'phone' :$('#phone').text(),
'code' :$('#code').text(),
'size' :$('#size').text(),
'isinvoice':$('[name=isinvoice]').val()
},
beforeSend:function(){
beforeSend.attr('disabled',true);
beforeSend.html('submitting').removeAttr('href');
},
success:function(data){
if(data.errorcode==1){
$('.pay-fail').show().text(data.message);
}else{
if(data.url){
location.href=data.url;
}else{
alert('post ok!');
}
}
},
error: function(){
alert('submit error,then try again');
}
})
This is my jQuery ajax for pay. It works on localhost and on server.

Showing events for multiple eventSources depend on checkboxes' choice in Fullcalendar

I'm adding the feature like in Solgema Fullcalendar - http://plone.org/products/solgema.fullcalendar/releases/2.1.2
(selecting and showing events with checkboxes selection)
My eventSourses look like:
eventSources: [
...
{
url: '/admin_schedule/get_schedule_db_recurring_events_on_daysweek/',//"<?echo $data_path?>",
type: 'GET',
data: {sch_teacher_id: sch_teacher_id},
backgroundColor: 'red',
}
],
And I want implement checkboxes for "filtering" events by teachers, checked in checkboxes. For beginning make just one checkbox (later make foreach cover)
<div class="box">
<?php
$js = 'onClick="rerender_schedule()"';
echo form_checkbox('teacher', 'vika', FALSE, $js)." Vika";
?>
</div>
By this code as I think, fullcalendar must call rerender_schedule() function which filters data from eventSource with vika's sch_teacher_id
If somebody could help with rerender_schedule() function, I will be thankful, because not good in ajax.
EDIT: (thanks to tocallaghan!). It's just a beginning right now.
My 3 checkboxes:
$data = array(
'name' => 'teacher',
'class' => 'teacher',
'id' => 'teacher',
'value' => '128',
'checked' => FALSE,
'style' => 'margin:10px',
);
echo form_checkbox($data); echo "Вика";
$data = array(
'name' => 'teacher',
'class' => 'teacher',
'id' => 'teacher2',
'value' => '111',
'checked' => FALSE,
'style' => 'margin:10px',
);
echo form_checkbox($data); echo "Вася";
$data = array(
'name' => 'teacher',
'class' => 'teacher',
'id' => 'teacher3',
'value' => '1',
'checked' => FALSE,
'style' => 'margin:10px',
);
echo form_checkbox($data); echo "Саша";
ajax on change them:
$('.teacher').change(function (event) {
events1.data.sch_teacher_id = $(this).val();
events2.data.sch_teacher_id = $(this).val();
events3.data.sch_teacher_id = $(this).val();
$calendar.fullCalendar('refetchEvents');
});
vars for eventSourses:
var events1 = {
url: 'url1',
type: 'GET',
data: {sch_teacher_id: $('#teacher').val() },
success: function (response) {
return response;
}
};
var events2 = {
url: 'url2',
type: 'GET',
data: {sch_teacher_id: $('#teacher').val() },
backgroundColor: 'green',
success: function (response) {
return response;
}
};
var events3 = {
url: 'url3',
type: 'GET',
data: { sch_teacher_id: $('#teacher').val() },
backgroundColor: 'red',
success: function (response) {
return response;
}
};
my eventSources call
eventSources: [
events1,
events2,
events3
],
You need refetchEvents , but be careful to update you data parameter before calling (otherwise it will remain the initially set value)
$('.CheckBoxClass').change(function () {
events.data.sch_teacher_id = $(this).val();
$('#calendar').fullCalendar('refetchEvents');
});
Edit: code to declare events object:
var events = {
url: 'url',
type: 'GET',
data: { Id: $('#divId').val() },
success: function (response) {
return response;
}
};
$('#calendar').fullCalendar({
events: events
});

Categories

Resources