Как обновить изображение с AJAX в Laravel - PullRequest
0 голосов
/ 24 октября 2019

У меня проблемы с обновлением записи с изображением. Я не то, что мне нужно делать. Мое изображение хранится в общей папке с именем 'img / products'

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);

        $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

Все, что я знаю, это то, что я должен использовать var formData = new FormData ($ ("# frmAddProduct") [0]);как в функции магазина. Я могу вводить записи с изображениями, но не редактировать их. Мое изображение хранится в общей папке с именем '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);
        }
    });
}

Ответы [ 2 ]

0 голосов
/ 24 октября 2019

Как-то так?

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();
            }
        });
    });
0 голосов
/ 24 октября 2019

Вы должны проверить, существует ли файл перед попыткой удаления, например:

 $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);
 }

Взгляните только на один пример:

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);
}

Было бы лучше, если вы создадитезапрос формы для проверки.

Не забудьте создать ссылки на путь хранения:

 php artisan storage:link 

Я думаю, это будет полезно:

 $("#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();
        }
    });
});

Является ли ваш сценарий JS в "Blade"? Если это так, попробуйте это следующим образом:

var image = '{{ asset("/img/products/_image_file") }}'

image.replace('_image_file', data.products.image)

$("#frmEditProduct file[name=image]").val(image)

Обратите внимание, что сначала мы можем использовать помощник "asset ()", чтобы создать полный путь для поиска изображения, но с заполнителем "_image_file". Послечто мы используем функцию replace (), чтобы заменить местозаполнитель "_image_file" на фактический файл изображения, полученный из ответа ajax.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...