So basically i am first time Metronic users so a lot of thing like including plugin etc is not familiar to me. I am using Laravel template for metronic for one of my project.
So i am trying to use the Draggable plugin: https://preview.keenthemes.com/html/metronic/docs/general/draggable/overview#usage
I followed the tutorial and included in my required page with the below script:
<script src="{{ asset("/assets/plugins/custom/draggable/draggable.bundle.js") }}" defer></script>
<script>
document.addEventListener("DOMContentLoaded", () => {
var containers = document.querySelectorAll(".draggable-zone");
if (containers.length === 0) {
return false;
}
var swappable = new Sortable.default(containers, {
draggable: ".draggable",
handle: ".draggable .draggable-handle",
mirror: {
//appendTo: selector,
appendTo: "body",
constrainDimensions: true
}
});
</script>
8:996 Uncaught ReferenceError: Sortable is not defined
at HTMLDocument.<anonymous> (8:996:17)
Hi,
Can you try to run your code in the bottom, after all core script includes within dom ready event as shown below:
KTUtil.onDOMContentLoaded(function () {
// your code
});
Within the same blade file?
Hi,
inside blade just use like this:
<script>
window.addEventListener("load", () => {
// your code
});
});
</script>
Still same, heres my updated blade file:
<x-default-layout>
@section("title")
Product Information
@endsection
@section("breadcrumbs")
{{ Breadcrumbs::render("categories.category-list") }}
@endsection
<div class="card mb-10">
<form method="POST" action="{{ route("product.update", $product->id) }}" enctype="multipart/form-data">
@csrf
@method("PUT")
<div class="mb-10">
<div class="card-header">
<h3 class="card-title">Upload Images
</div>
<div class="card-body">
<div class="mb-10">
<div class="dropzone" >
<!--begin::Message-->
<div class="dz-message needsclick">
<i class="ki-duotone ki-file-up fs-3x text-primary"><span class="path1"></span><span class="path2"></span></i>
<!--begin::Info-->
<div class="ms-4">
<h3 class="fs-5 fw-bold text-gray-900 mb-1">Drop files here or click to upload.
<span class="fs-7 fw-semibold text-gray-500">Upload up to 10 files</span>
</div>
<!--end::Info-->
</div>
</div>
</div>
<div class="mb-10">
<div class="image-container">
@foreach($product->images as $image)
<div class="image-input image-input-outline" data-kt-image-input="true" >
<!--begin::Image preview wrapper-->
<div class="image-input-wrapper w-125px h-125px" ></div>
<span class="btn remove-avatar-btn btn-icon btn-circle btn-color-muted btn-active-color-primary w-25px h-25px bg-body shadow"
data-kt-image-input-action="change"
data-bs-toggle="tooltip"
data-bs-dismiss="click"
data-image-
title="Remove">
<i class="ki-outline ki-cross fs-3"></i>
</span>
</div>
@endforeach
</div>
<div class="row row-cols-lg-2 g-10 draggable-zone">
<div class="col draggable">
<!--begin::Card-->
<div class="card card-bordered">
...
</div>
<!--end::Card-->
</div>
<div class="col draggable">
<!--begin::Card-->
<div class="card card-bordered">
...
</div>
<!--end::Card-->
</div>
<div class="col draggable">
<!--begin::Card-->
<div class="card card-bordered">
...
</div>
<!--end::Card-->
</div>
<div class="col draggable">
<!--begin::Card-->
<div class="card card-bordered">
...
</div>
<!--end::Card-->
</div>
<div class="col draggable">
<!--begin::Card-->
<div class="card card-bordered">
...
</div>
<!--end::Card-->
</div>
<div class="col draggable">
<!--begin::Card-->
<div class="card card-bordered">
...
</div>
<!--end::Card-->
</div>
<div class="col draggable">
<!--begin::Card-->
<div class="card card-bordered">
...
</div>
<!--end::Card-->
</div>
<div class="col draggable">
<!--begin::Card-->
<div class="card card-bordered">
...
</div>
<!--end::Card-->
</div>
<div class="col draggable">
<!--begin::Card-->
<div class="card card-bordered">
...
</div>
<!--end::Card-->
</div>
<div class="col draggable">
<!--begin::Card-->
<div class="card card-bordered">
...
</div>
<!--end::Card-->
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div class="card card-flush mb-10">
<div class="card-header">
<h3 class="card-title">Product Details
</div>
<div class="card-body">
<!-- Product Title -->
<div class="mb-10">
<label class="form-label required">Product Title</label>
<input type="text" class="form-control" placeholder="Enter title" name="name" maxlength="20" value="{{ $product->name }}">
<span class="form-text text-muted">Do not exceed 20 characters when entering the product name.</span>
</div>
<!-- Category -->
<div class="row g-9 mb-10">
<div class="col-md-6">
<label class="form-label">Category</label>
<input type="text" class="form-control" placeholder="Category" name="category" value="{{$product->category->name}}" disabled>
<input type="hidden" name="category_id" value="{{ $product->category->id }}">
</div>
<!-- Price -->
<div class="col-md-6">
<label class="form-label required">Price</label>
<input type="number" class="form-control" placeholder="Price" name="price" value="{{$product->price}}" >
</div>
</div>
<div class="row">
<!-- Left Column -->
<div class="col-md-6 mb-10">
<!--begin::Input wrapper-->
<div class="d-flex flex-column mb-8 fv-row">
<!--begin::Label-->
<label class="d-flex align-items-center fs-6 fw-semibold mb-2">
<span class="required">Size</span>
</label>
<!--end::Label-->
<!--begin::Buttons-->
<div >
@foreach ($product->category->sizes as $size)
<div class="form-group row mb-2 align-items-center">
<div class="col-md-1 d-flex align-items-center">
<label class="form-label">{{ $size }}</label>
</div>
<div class="col-md-3 d-flex align-items-center">
<input type="number" class="form-control mb-2 mb-md-0" placeholder="Enter Stock" name="quantities[{{ $size }}]" value="{{ $quantities[$size] ?? 0 }}" />
</div>
</div>
@endforeach
</div>
</div>
</div>
<!-- Right Column -->
<div class="col-md-6 mb-10">
<!-- Wrapper Div to Handle Structure and Spacing -->
<div class="d-flex flex-column">
<!-- Checkbox to Toggle the Collapsible Section -->
{{-- <label class="btn btn-outline btn-outline-dashed d-flex text-start p-6 align-items-start">
<input type="hidden" name="has_discount" value="0">
<!-- Checkbox for Selling Price -->
<span class="form-check form-check-custom form-check-solid form-check-sm mt-1">
<input
name="has_discount"
class="form-check-input"
type="checkbox"
value="1"
data-bs-toggle="collapse"
data-bs-target="#sellingPriceOptions"
aria-expanded="false"
aria-controls="sellingPriceOptions"
/>
</span>
<!-- Info and Label Text -->
<span class="ms-5 d-flex flex-column">
<span class="fs-4 fw-bold text-gray-800 text-nowrap mb-2" for="sellingPriceToggle">Discount Price</span>
<!-- Collapsible Section for Sale Price and Schedule -->
<div class=" mt-4">
<!-- Sale Price Input -->
<div class="mb-10">
<label class="form-label">Sale Price</label>
<input type="number" class="form-control" placeholder="Discount Price" name="discount_price">
</div>
<!-- Schedule Input -->
<div>
<label class="form-label">Schedule</label>
<input type="date" class="form-control" name="discount_date">
</div>
</div>
</span>
</label> --}}
<label class="btn btn-outline btn-outline-dashed d-flex text-start p-6 align-items-start">
<input type="hidden" name="has_discount" value="0">
<!-- Checkbox for Selling Price -->
<span class="form-check form-check-custom form-check-solid form-check-sm mt-1">
<input
name="has_discount"
class="form-check-input"
type="checkbox"
value="1"
checked = {{$product->has_discount ? "checked" : ""}}
/>
</span>
<!-- Info and Label Text -->
<span class="ms-5 d-flex flex-column">
<span class="fs-4 fw-bold text-gray-800 text-nowrap mb-2" for="sellingPriceToggle">Discount Price</span>
<!-- Section for Sale Price and Schedule -->
<div class="mt-4">
<!-- Sale Price Input -->
<div class="mb-10">
<label class="form-label">Sale Price</label>
<input type="number" class="form-control" placeholder="Discount Price" name="discount_price" {{$product->has_discount ? "" : "disabled"}} value="{{$product->discount_price == null ? "0.0" : $product->discount_price}}">
</div>
<!-- Schedule Input -->
<div>
<label class="form-label">Schedule</label>
<input type="date" class="form-control" name="discount_date" value={{date("Y-m-d", strtotime($product->discount_date))}} {{$product->has_discount ? "" : "disabled"}}>
</div>
</div>
</span>
</label>
</div>
</div>
</div>
<div class="row g-9 mb-10">
<!-- Variant: Color -->
<div class="col-md-4">
<label class="form-label">Color</label>
<input type="text" class="form-control" placeholder="Choose color" name="color" value={{$product->color}} >
</div>
<!-- SKU -->
<div class="col-md-4">
<label class="form-label">SKU</label>
<input type="text" class="form-control" placeholder="Enter SKU" name="sku" value={{$product->sku}}>
</div>
<div class="d-flex col-md-4 align-items-center">
<label class="d-flex align-items-center fs-6 fw-semibold mb-2">
<span>Best Seller </span>
<input
name="best_seller"
class="form-check-input"
type="checkbox"
value="1"
{{$product->best_seller ? "checked" : ""}}
/>
</label>
</div>
{{-- <!-- Tags -->
<div class="col-md-4">
<label class="form-label">Tags</label>
<input type="text" class="form-control" placeholder="Enter a tag" name="tags">
</div> --}}
</div>
<!-- Description -->
<div class="mb-10">
<label class="form-label required">Description</label>
<textarea class="form-control" name="description" placeholder="Short description about product" maxlength="100" >{{$product->description}}</textarea>
<span class="form-text text-muted">Do not exceed 100 characters when entering the description.</span>
</div>
</div>
<!--begin::Actions-->
<div class="card-footer d-flex justify-content-end py-6 px-9">
{{-- <button type="reset" class="btn btn-light btn-active-light-primary me-2">Discard</button> --}}
<button type="submit" class="btn btn-primary">Save Changes</button>
</div>
<!--end::Actions-->
</div>
</form>
</div>
<script src="{{ asset("assets/plugins/custom/draggable/draggable.bundle.js") }}" defer></script>
<script>
window.addEventListener("load", () => {
var containers = document.querySelectorAll(".draggable-zone");
if (containers.length === 0) {
return false;
}
var swappable = new Sortable.default(containers, {
draggable: ".draggable",
handle: ".draggable .draggable-handle",
mirror: {
//appendTo: selector,
appendTo: "body",
constrainDimensions: true
}
});
});
</script>
</x-default-layout>