A. Single Photo
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script> <link href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.12/cropper.min.css" rel="stylesheet"> <script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.12/cropper.min.js"></script>
<div class="container"> <div class="item up-load"> <input type="file" id="product_thumbnail" name="product_thumbnail" required> <input type="hidden" name="cropped_thumbnail" id="cropped_thumbnail"> </div> <div class="upload-image mb-16 upload-thumbs"> <img id="imagePreview" style="max-width: 100%; display:none;"> </div> <div class="btngroup"> <button id="cropButton" class="btn btn-success">Crop</button> <button id="skipButton">Skip Cropping</button> </div> </div>
<script> $(document).ready(function(){ $('#skipButton').click(function(){ $('.upload-thumbs').hide(); $('.btngroup').hide(); const formData = new FormData(); var property = document.getElementById('product_thumbnail').files[0]; formData.append('image', property); formData.append('_token', '{{ csrf_token() }}'); // CSRF Token $.ajax({ url: "{{route('upload_thumbnail_crop')}}", method: 'POST', data: formData, processData: false, contentType: false, beforeSend: function() { $('#uploadedImage').html('<h3>Loading..</h3>'); }, success: function(response) { let baseurl = "{{asset('/')}}"; let path = baseurl+'product_thumbnail/'+response.filename; $('#uploadedImage').html('<img src="'+path+'" style="height:100px" />'); $('#cropped_thumbnail').val(response.filename); // alert('success'); }, error: function() { alert('Something went wrong!'); } }); }); }); </script>
<script> let cropper; $('#product_thumbnail').on('change', function(e) { $('#cropButton').show(); $('#skipButton').show(); $('.upload-thumbs').show(); $('.btngroup').show(); const file = e.target.files[0]; var fileName = $(this).val().split('\\').pop(); $('#cropped_thumbnail').val(fileName); if (file) { const reader = new FileReader(); reader.onload = function(e) { $('#imagePreview').attr('src', e.target.result).show(); if (cropper) { cropper.destroy(); } cropper = new Cropper(document.getElementById('imagePreview'), { aspectRatio: 1, // Change ratio as needed viewMode: 2, preview: '#croppedImagePreview', }); } reader.readAsDataURL(file); } }); $('#cropButton').on('click', function() { if (cropper) { cropper.getCroppedCanvas().toBlob((blob) => { const formData = new FormData(); formData.append('image', blob); formData.append('_token', '{{ csrf_token() }}'); // CSRF Token $.ajax({ url: "{{route('upload_thumbnail_crop')}}", method: 'POST', data: formData, processData: false, contentType: false, beforeSend: function() { $('#uploadedImage').html('<h3>Loading..</h3>'); }, success: function(response) { let baseurl = "{{asset('/')}}"; let path = baseurl+'/upload_thumbnail_crop/'+response.filename; $('#croppedImagePreview').attr('src', path); }, error: function() { alert('Something went wrong!'); } }); }); } }); </script>
use App\Http\Controllers\ImageController; Route::get('/', function () { return view('index'); }); Route::post('/upload-thumbnail-crop', [ImageController::class, 'upload'])->name('upload_thumbnail_crop');
namespace App\Http\Controllers; use Illuminate\Http\Request; class ImageController extends Controller { function upload_thumbnail_crop(Request $request){ $cropped_thumbnail = $req->cropped_thumbnail; if ($request->hasFile('image')) { $image = $request->file('image'); $filename = time() . '.jpg'; // You can use png, jpg, or webp $image->move(public_path('upload_thumbnail_crop'), $filename); return response()->json(['filename' => $filename]); } return response()->json(['error' => 'No image uploaded!']); } }
B. Gallery Photo
$maxNumber = 110; <?php for ($i=1; $i < $maxNumber; $i++) { ?> <script> $(document).ready(function(){ $('#add_more_galleries{{$i}}').click(function(){ $(".add_more_gallery_images{{$i+1}}").show(); $(this).hide(); $("#add_more_galleries{{$i+1}}").show(); }); }); </script> <?php } ?>
<?php for ($i=1; $i < $maxNumber; $i++) { ?> <!-- gallery images start --> <div class="add_more_gallery_images{{$i}}"> <!-- start --> <div class="upload-image mb-16 upload_thumbs{{$i}}"> <img id="imagePreviewGallery{{$i}}" style="max-width: 100%; display:none;"> </div> <div class="upload-image mb-16 btngroup2"> <button id="cropButtonGallery{{$i}}" class="btn btn-warning" type="button" style="display:none;">Crop</button> <button id="skipButton{{$i}}" class="btn btn-dark" type="button" style="display:none;">Skip Cropping</button> </div> <script> $(document).ready(function(){ $('#skipButton{{$i}}').click(function(){ $('.upload_thumbs{{$i}}').hide(); $('.btngroup{{$i}}').hide(); const formData = new FormData(); var property = document.getElementById('product_gallery{{$i}}').files[0]; formData.append('image', property); formData.append('_token', '{{ csrf_token() }}'); // CSRF Token $.ajax({ url: "{{route('upload_thumbnail_crop')}}", method: 'POST', data: formData, processData: false, contentType: false, beforeSend: function() { $('#uploadedImageGallery{{$i}}').html('<h3>Loading..</h3>'); }, success: function(response) { let baseurl = "{{asset('/')}}"; let path = baseurl+'product_thumbnail/'+response.filename; $('#uploadedImageGallery{{$i}}').html('<img src="'+path+'" style="height:100px" />'); $('#cropped_gallery{{$i}}').val(response.filename); // alert('success'); }, error: function() { alert('Something went wrong!'); } }); }); }); </script>
<button class="tf-button w-fulls" id="add_more_galleries1" type="button" style="margin-top:-20px">Add More +</button> <?php for ($i=2; $i < $maxNumber-1; $i++) { ?> <button class="tf-button w-fulls" id="add_more_galleries{{$i}}" type="button" style="margin-top:-20px; display:none;">Add More +</button> <?php } ?> <br/>
<?php for ($i=1; $i < $maxNumber; $i++) { ?> <script> $(document).ready(function(){ $('#add_more_galleries{{$i}}').click(function(){ $(".add_more_gallery_images{{$i+1}}").show(); $(this).hide(); $("#add_more_galleries{{$i+1}}").show(); }); }); </script> <?php } ?>
<?php for ($i=2; $i < $maxNumber; $i++) { ?> <style> .add_more_gallery_images{{$i}}{ display:none; } </style> <?php } ?>
<?php for ($i=1; $i < $maxNumber; $i++) { ?> <div class="upload-image mb-16"> <div class="item"> <div id="uploadedImageGallery{{$i}}"></div> </div> </div> <!-- end --> <style>.upload-image .item img{height:auto}</style> <div class="upload-image mb-16"> <div class="item up-load"> <input type="file" id="product_gallery{{$i}}" name="product_gallery[]" class="product_gallery{{$i}}" required> <input type="hidden" name="cropped_gallery[]" id="cropped_gallery{{$i}}"> </div> </div> </div> <!-- gallery images end --> </fieldset> <br><br/> <button class="tf-button w-fulls" id="add_more_galleries{{$i}}" type="button" style="margin-top:-20px"> Add More +</button> <?php } ?>
Controller.php
function save_products(Request $req){
$validated = $req->validate([
'product_name'=>'required',
'regular_price'=>'required',
'stock'=>'required',
'collections'=>'required',
'category'=>'required',
's_description'=>'required',
'l_description'=>'required',
]);
$product_name = $req->product_name;
$attribute_name_arr = $req->attribute_name;
$attributes_value_arr = $req->attributes_value;
$regular_price_arr = $req->regular_price;
$sale_price_arr = $req->sale_price;
$cropped_gallery_arr = $req->cropped_gallery;
$stock_arr = $req->stock;
$collections = $req->collections;
$category = $req->category;
$subcategory = $req->subcategory;
$s_description = $req->s_description;
$l_description = $req->l_description;
$status = $req->status;
if($req->cropped_thumbnail){
$thumurl = $req->cropped_thumbnail;
}
else{
$file = $req->file('product_thumbnail'); // your base64 encoded
// return $file;
$filename = time().'_pk.'.$req->file('product_thumbnail')->getClientOriginalExtension();
$filestore = $req->file('product_thumbnail')->move(public_path('product_thumbnail'), $filename);
$thumurl = $filename;
}
// $product_gallery_arr = [];
if ($req->hasfile('product_gallery')) {
foreach ($req->file('product_gallery') as $file) {
$name = $file->getClientOriginalName();
$file->move(public_path() . '/product_gallery/', $name);
$product_gallery_arr[] = $name;
}
}
// return $regular_price;
$attributes_value_str = implode(",",$attributes_value_arr);
$regular_price_str = implode(",",$regular_price_arr);
$sale_price_str = implode(",",$sale_price_arr);
$stock_str = implode(",",$stock_arr);
$attribute_name_str = implode(',', $attribute_name_arr);
$product_gallery_str = implode(",",$cropped_gallery_arr);
// return $attribute_name_arr;
$insertGetId = '';
$insertGetId = DB::table('products')->insert([
'user_id' => auth()->user()->id,
'name' => $product_name,
'collection' => $collections,
'category' => $category,
'attr_key' => $attribute_name_str,
'attr_value' => $attributes_value_str,
'subcategory' => $subcategory,
'short_description' => $s_description,
'long_description' => $l_description,
'status' => $status,
'variations' => $attributes_value_str,
'regular_price' => $regular_price_str,
'sale_price' => $sale_price_str,
'stock' => $stock_str,
'slider_images' => $product_gallery_str,
'thumbnail' => $thumurl,
]);
return back()->with('msg', 'Product saved successfully !');
}
function upload_thumbnail_crop(Request $request){ if ($request->hasFile('image')) { $image = $request->file('image'); $filename = time() . '.jpg'; // You can use png, jpg, or webp $image->move(public_path('product_thumbnail'), $filename); return response()->json(['filename' => $filename]); } return response()->json(['error' => 'No image uploaded!']); }