473 lines
17 KiB
PHP
473 lines
17 KiB
PHP
@extends('user.layout')
|
|
@section('title', 'Data Training')
|
|
@section('content')
|
|
<div class="modal fade" tabindex="-1" id="modalAddTraining" aria-labelledby="modalAddTrainingLabel"
|
|
data-bs-backdrop="static" data-bs-keyboard="false" role="dialog" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 id="modalAddTrainingLabel" class="modal-title">
|
|
Tambah Data Training
|
|
</h5>
|
|
<button type="button" class="btn-close text-reset" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form id="addNewTrainingForm">@csrf
|
|
<input type="hidden" name="id" id="train_id">
|
|
<div class="form-floating mb-3">
|
|
<input type="text" class="form-control" id="trainName" name="nama" placeholder="Nama" required />
|
|
<label for="trainName">Nama</label>
|
|
<div class="invalid-feedback" id="name-error"></div>
|
|
</div>
|
|
@foreach ($atribut as $attr)
|
|
<div class="form-floating mb-3" data-bs-toggle="tooltip" title="{{$attr->desc}}">
|
|
@if ($attr->type==='numeric')
|
|
<input type="number" class="form-control" min="0" name="q[{{$attr->slug}}]" placeholder="123"
|
|
id="train-{{$attr->slug}}" required>
|
|
@else
|
|
<select name="q[{{$attr->slug}}]" class="form-select" id="train-{{$attr->slug}}" required>
|
|
<option value="">Pilih</option>
|
|
@foreach ($nilai->where('atribut_id', $attr->id) as $sub)
|
|
<option value="{{$sub->id}}">{{$sub->name}}</option>
|
|
@endforeach
|
|
</select>
|
|
@endif
|
|
<label for="train-{{$attr->slug}}">{{$attr->name}}</label>
|
|
<div class="invalid-feedback" id="{{$attr->slug}}-error"></div>
|
|
</div>
|
|
@endforeach
|
|
<div class="form-floating mb-3">
|
|
<select name="status" class="form-select" id="trainResult" required>
|
|
<option value="">Pilih</option>
|
|
<option value="1">{{$hasil[true]}}</option>
|
|
<option value="0">{{$hasil[false]}}</option>
|
|
</select>
|
|
<label for="trainResult">Hasil</label>
|
|
<div class="invalid-feedback" id="result-error"></div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="reset" class="btn btn-secondary" data-bs-dismiss="modal">
|
|
<i class="fas fa-x"></i> Batal
|
|
</button>
|
|
<button type="button" class="btn btn-success" data-bs-toggle="modal"
|
|
data-bs-target="#modalImportTraining">
|
|
<i class="fas fa-upload"></i> Upload File
|
|
</button>
|
|
<button type="submit" class="btn btn-primary" form="addNewTrainingForm">
|
|
<i class="fas fa-floppy-disk"></i> Simpan
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal fade" tabindex="-1" id="modalImportTraining" aria-labelledby="modalImportTrainingLabel"
|
|
data-bs-backdrop="static" data-bs-keyboard="false" role="dialog" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 id="modalImportTrainingLabel" class="modal-title">Upload Data Training</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="alert alert-info" role="alert">
|
|
<i class="fas fa-info-circle"></i>
|
|
<a href="{{route('template-data')}}" class="alert-link">Klik disini</a>
|
|
untuk mendownload template Dataset
|
|
</div>
|
|
<form id="importTrainingData" enctype="multipart/form-data">@csrf
|
|
<input type="file" class="form-control" id="trainData" name="data" data-bs-toggle="tooltip"
|
|
title="Format: xls, xlsx, csv, dan tsv" aria-describedby="importFormats"
|
|
accept="application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.oasis.opendocument.spreadsheet,text/csv,.tsv"
|
|
required>
|
|
<div class="invalid-tooltip" id="data-error"></div>
|
|
</form>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="reset" class="btn btn-secondary" data-bs-dismiss="modal">
|
|
<i class="fas fa-x"></i> Batal
|
|
</button>
|
|
<button type="button" class="btn btn-success" data-bs-toggle="modal" data-bs-target="#modalAddTraining">
|
|
<i class="fas fa-pen"></i> Input Manual
|
|
</button>
|
|
<button type="submit" class="btn btn-primary" form="importTrainingData">
|
|
<i class="fas fa-upload"></i> Upload
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-sm-6 mb-3">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-start justify-content-between">
|
|
<div class="content-left">
|
|
<span>Jumlah</span>
|
|
<div class="d-flex align-items-end mt-2">
|
|
<h3 class="mb-0 me-2"><span id="total-counter">-</span></h3>
|
|
</div>
|
|
</div>
|
|
<span class="badge bg-primary rounded p-2">
|
|
<i class="fas fa-list-ul"></i>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6 mb-3">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-start justify-content-between">
|
|
<div class="content-left">
|
|
<span>Duplikat</span>
|
|
<div class="d-flex align-items-end mt-2">
|
|
<h3 class="mb-0 me-2"><span id="total-duplicate">-</span></h3>
|
|
</div>
|
|
</div>
|
|
<span class="badge bg-warning rounded p-2">
|
|
<i class="fas fa-copy"></i>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="alert alert-info alert-dismissible" role="alert">
|
|
<p>Data Training (Data Latih) digunakan untuk melatih algoritma klasifikasi Naive Bayes.
|
|
Jika Anda melakukan perubahan pada Data Training, Probabilitas akan direset secara otomatis.</p>
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
|
</div>
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="btn-group mb-2" role="group">
|
|
@if (auth()->user()->level==1)
|
|
<div class="btn-group" role="group">
|
|
<button class="btn btn-primary dropdown-toggle" type="button" data-bs-toggle="dropdown"
|
|
aria-expanded="false">
|
|
<i class="fas fa-plus"></i> Tambah Data <i class="fa-solid fa-caret-down"></i>
|
|
</button>
|
|
<ul class="dropdown-menu">
|
|
<li>
|
|
<a class="dropdown-item" href="#modalAddTraining" data-bs-toggle="modal">
|
|
<i class="fas fa-pen"></i> Input Manual
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a class="dropdown-item" href="#modalImportTraining" data-bs-toggle="modal">
|
|
<i class="fas fa-upload"></i> Upload File
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<button type="button" class="btn btn-danger" id="delete-all">
|
|
<i class="fas fa-trash"></i> Hapus Data
|
|
</button>
|
|
|
|
@endif
|
|
|
|
<a href="{{route('training.export')}}" class="btn btn-success disabled" id="dlBtn">
|
|
<i class="fas fa-download"></i> Ekspor Data
|
|
</a>
|
|
</div>
|
|
<table class="table table-bordered" id="table-training" width="100%">
|
|
<thead>
|
|
<tr>
|
|
<th>#</th>
|
|
<th>Nama</th>
|
|
@foreach ($atribut as $attr)
|
|
<th>
|
|
{{$attr->name}}
|
|
</th>
|
|
@endforeach
|
|
<th>Hasil</th>
|
|
</tr>
|
|
</thead>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="mt-4">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="card h-100">
|
|
<div class="card-body">
|
|
<h5 class="card-title">Solusi untuk Mengatasi pH Tanah yang Asam</h5>
|
|
<p class="card-text"> 1. Pemberian kapur pertanian pada tanah
|
|
<br> 2. Pemberian pupuk NPK sesuai kebutuhan
|
|
<br> 3. Memperbaiki drainase</p>
|
|
<h5 class="card-title">Solusi untuk Mengatasi pH Tanah yang Basa</h5>
|
|
<p class="card-text"> 1. Memberikan bubuk belerang atau sulfur
|
|
<br> 2. Menggunakan pupuk kompos</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="card h-100">
|
|
<div class="card-body">
|
|
<h5 class="card-title">Solusi untuk Mengatasi Suhu yang Tidak Normal</h5>
|
|
<p class="card-text"> 1. Mengatur Pengairan agar menjaga suhu tanah tetap stabil
|
|
<br> 2. Menggunakan mulsa jerami ataupun plastik untuk menjaga suhu<br> untuk tanaman jagung dan tembakau<br> tanah</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6 mt-2">
|
|
<div class="card h-100">
|
|
<div class="card-body">
|
|
<h5 class="card-title">Solusi untuk Mengatasi Kelembaban yang Tidak Normal</h5>
|
|
<p class="card-text"> 1. Menggunakan mulsa untuk menjaga kelembaban tanah untuk<br> tanaman jagung dan tembakau
|
|
<br> 2. Memastikan sistem drainase yang baik</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6 mt-2">
|
|
<div class="card h-100">
|
|
<div class="card-body">
|
|
<h5 class="card-title">Solusi untuk Mengatasi Intensitas Cahaya yang Tidak Normal</h5>
|
|
<p class="card-text"> 1. Melakukan Penanaman diarea terbuka tidak terdapat bangunan atau<br> tanaman lain yang menghalangi
|
|
<br> 2. Sesuaikan jarak tanaman dan lakukan pemangkasan untuk tanaman<br> jagung dan tembakau
|
|
<br> 3. Gunakan peneduh seperti jaring ataupun paranet untuk mengurangi<br> intensitas cahaya</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endsection
|
|
@section('js')
|
|
<script type="text/javascript">
|
|
let dt_training = $("#table-training"), errmsg;
|
|
const modalForm = $("#modalAddTraining");
|
|
$(document).ready(function () {
|
|
try {
|
|
$.fn.dataTable.ext.errMode = "none";
|
|
dt_training = dt_training.DataTable({
|
|
stateSave: true,
|
|
lengthChange: false,
|
|
serverSide: true,
|
|
processing: true,
|
|
responsive: true,
|
|
searching: false,
|
|
ajax: "{{ route('training.create') }}",
|
|
columns: [
|
|
{ data: "id" },
|
|
{ data: "nama" },
|
|
@foreach ($atribut as $attr)
|
|
{ data: "{{$attr->slug}}" },
|
|
@endforeach
|
|
{ data: "status" },
|
|
],
|
|
columnDefs: [{
|
|
targets: 0,
|
|
searchable: false,
|
|
render: function (data, type, full, meta) {
|
|
return meta.settings._iDisplayStart + meta.row + 1;
|
|
}
|
|
},
|
|
@foreach ($atribut as $attr)
|
|
{
|
|
targets: 2 + {{$loop->index}},
|
|
render: function(data){
|
|
return data ?? "?";
|
|
}
|
|
},
|
|
@endforeach
|
|
],
|
|
language: {
|
|
url: "https://cdn.datatables.net/plug-ins/2.0.0/i18n/id.json"
|
|
}
|
|
}).on("dt-error", function (e, settings, techNote, message) {
|
|
errorDT(message, techNote);
|
|
}).on('xhr', function () {
|
|
$.get("{{ route('training.count') }}", function (data) {
|
|
if(data.total==0) $('#dlBtn').addClass('disabled');
|
|
else $('#dlBtn').removeClass('disabled');
|
|
$("#total-counter").text(data.total);
|
|
$('#total-duplicate').text(data.duplicate);
|
|
}).fail(function (xhr, st) {
|
|
console.warn(xhr.responseJSON.message ?? st);
|
|
Notiflix.Notify.failure(
|
|
`Gagal memuat jumlah: Kesalahan HTTP ${xhr.status} ${xhr.statusText}`
|
|
);
|
|
});
|
|
});
|
|
} catch (dterr) {
|
|
initError(dterr.message);
|
|
}
|
|
}).on("click", "#delete-all", function () {
|
|
Notiflix.Confirm.show(
|
|
"Hapus semua Data Training?",
|
|
'Anda akan menghapus semua Data Training yang akan mereset hasil klasifikasi terkait.',
|
|
'Ya',
|
|
'Tidak',
|
|
function () {
|
|
$.ajax({
|
|
type: "DELETE",
|
|
headers: { "X-CSRF-TOKEN": "{{ csrf_token() }}" },
|
|
url: "{{route('training.clear')}}",
|
|
beforeSend: function(){
|
|
Notiflix.Loading.standard('Menghapus');
|
|
},complete:function(){
|
|
Notiflix.Loading.remove();
|
|
},
|
|
success: function () {
|
|
if ($.fn.DataTable.isDataTable("#table-training"))
|
|
dt_training.draw();
|
|
Notiflix.Notify.success("Semua data berhasil dihapus");
|
|
},
|
|
error: function (xhr, st) {
|
|
console.warn(xhr.responseJSON.message ?? st);
|
|
Notiflix.Notify.failure(
|
|
`Gagal hapus: Kesalahan HTTP ${xhr.status} ${xhr.statusText}`);
|
|
}
|
|
});
|
|
}
|
|
);
|
|
}).on("click", ".delete-record", function () {
|
|
let train_id = $(this).data("id"), train_name = $(this).data("name");
|
|
Notiflix.Confirm.show(
|
|
"Hapus Data Training?",
|
|
`Anda akan menghapus Data Training ${train_name}.`,
|
|
'Ya',
|
|
'Tidak',
|
|
function () {
|
|
$.ajax({
|
|
type: "DELETE",
|
|
headers: { "X-CSRF-TOKEN": "{{ csrf_token() }}" },
|
|
url: 'training/' + train_id,
|
|
beforeSend: function(){
|
|
Notiflix.Loading.standard('Menghapus');
|
|
},complete:function(){
|
|
Notiflix.Loading.remove();
|
|
},
|
|
success: function () {
|
|
dt_training.draw();
|
|
Notiflix.Notify.success("Berhasil dihapus");
|
|
},
|
|
error: function (xhr, st) {
|
|
if (xhr.status === 404) {
|
|
dt_training.draw();
|
|
errmsg = `Data Training ${train_name} tidak ditemukan`;
|
|
} else {
|
|
console.warn(xhr.responseJSON.message ?? st);
|
|
errmsg = `Kesalahan HTTP ${xhr.status} ${xhr.statusText}`;
|
|
}
|
|
Notiflix.Notify.failure('Gagal hapus: ' + errmsg);
|
|
}
|
|
});
|
|
}
|
|
);
|
|
}).on("click", ".edit-record", function () {
|
|
let train_id = $(this).data("id");
|
|
$("#modalAddTrainingLabel").text("Edit Data Training");
|
|
Notiflix.Block.standard('.modal-content','Memuat');
|
|
$.get(`training/${train_id}/edit`, function (data) {
|
|
$("#train_id").val(data.id);
|
|
$("#trainName").val(data.nama);
|
|
$('#trainResult').val(data.status);
|
|
@foreach($atribut as $attr)
|
|
$("#train-{{$attr->slug}}").val(data.{{$attr->slug}});
|
|
@endforeach
|
|
}).fail(function (xhr, st) {
|
|
if (xhr.status === 404) {
|
|
dt_training.draw();
|
|
modalForm.modal('hide');
|
|
errmsg = "Data yang Anda cari tidak ditemukan";
|
|
} else {
|
|
console.warn(xhr.responseJSON.message ?? st);
|
|
errmsg = `Kesalahan HTTP ${xhr.status} ${xhr.statusText}`;
|
|
}
|
|
Notiflix.Notify.failure("Gagal memuat data: "+errmsg);
|
|
}).always(function () {
|
|
Notiflix.Block.remove('.modal-content');
|
|
});
|
|
});
|
|
$('#importTrainingData').submit(function(e){//form Upload Data
|
|
e.preventDefault();
|
|
$.ajax({
|
|
type: "POST",
|
|
url: "{{route('training.import')}}",
|
|
dataType: 'JSON',
|
|
data: new FormData(this),
|
|
contentType: false,
|
|
cache: false,
|
|
processData: false,
|
|
beforeSend: function () {
|
|
resetvalidation();
|
|
Notiflix.Block.standard('.modal-content','Mengupload');
|
|
},
|
|
complete: function () {
|
|
Notiflix.Block.remove('.modal-content');
|
|
},
|
|
success: function (status) {
|
|
if ($.fn.DataTable.isDataTable("#table-training")) dt_training.draw();
|
|
$('#modalImportTraining').modal("hide");
|
|
Notiflix.Notify.success("Berhasil diupload");
|
|
},
|
|
error: function (xhr, st) {
|
|
$("#trainData").addClass("is-invalid");
|
|
$("#data-error").text(xhr.responseJSON.message);
|
|
if (xhr.status === 422) errmsg = xhr.responseJSON.message;
|
|
else {
|
|
console.warn(xhr.responseJSON.message ?? st);
|
|
errmsg = `Kesalahan HTTP ${xhr.status} ${xhr.statusText}`;
|
|
}
|
|
Notiflix.Notify.failure("Gagal upload: "+errmsg);
|
|
}
|
|
});
|
|
});
|
|
$("#addNewTrainingForm").submit(function (ev) {//form Input Manual
|
|
ev.preventDefault();
|
|
$.ajax({
|
|
data: $("#addNewTrainingForm").serialize(),
|
|
url: "{{ route('training.store') }}",
|
|
type: "POST",
|
|
beforeSend: function () {
|
|
resetvalidation();
|
|
Notiflix.Block.standard('.modal-content','Menyimpan');
|
|
},
|
|
complete: function () {
|
|
Notiflix.Block.remove('.modal-content');
|
|
},
|
|
success: function (status) {
|
|
if ($.fn.DataTable.isDataTable("#table-training")) dt_training.draw();
|
|
modalForm.modal("hide");
|
|
Notiflix.Notify.success(status.message);
|
|
},
|
|
error: function (xhr, st) {
|
|
if (xhr.status === 422) {
|
|
if (typeof xhr.responseJSON.errors.nama !== "undefined") {
|
|
$("#trainName").addClass("is-invalid");
|
|
$("#name-error").text(xhr.responseJSON.errors.nama);
|
|
}
|
|
@foreach($atribut as $attr)
|
|
if (typeof xhr.responseJSON.errors.{{$attr->slug}} !== "undefined") {
|
|
$("#train-{{$attr->slug}}").addClass("is-invalid");
|
|
$("#{{$attr->slug}}-error").text(xhr.responseJSON.errors.{{$attr->slug}});
|
|
}
|
|
@endforeach
|
|
if (typeof xhr.responseJSON.errors.status !== "undefined") {
|
|
$("#trainResult").addClass("is-invalid");
|
|
$("#status-error").text(xhr.responseJSON.errors.status);
|
|
}
|
|
errmsg = xhr.responseJSON.message;
|
|
} else {
|
|
console.warn(xhr.responseJSON.message ?? st);
|
|
errmsg = `Terjadi kesalahan HTTP ${xhr.status} ${xhr.statusText}`;
|
|
}
|
|
Notiflix.Notify.failure(errmsg);
|
|
}
|
|
});
|
|
});
|
|
modalForm.on("hidden.bs.modal", function () {
|
|
resetvalidation();
|
|
$("#modalAddTrainingLabel").text("Tambah Data Training");
|
|
$("#addNewTrainingForm")[0].reset();
|
|
$("#train_id").val("");
|
|
});
|
|
$('#modalImportTraining').on('hidden.bs.modal',function(){
|
|
resetvalidation();
|
|
$("#importTrainingData")[0].reset();
|
|
});
|
|
</script>
|
|
@endsection
|