Level 8
@omar_hamwi hey when will you get solution please mention me.
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
hey so i have a laravel project that displays the data using yajra datatables in the table i have multiple select buttons what i want to do is to select multiple rows an edit them at the same time how can i do that this is my blade file
<x-app-layout>
<x-slot name="header">
<h2 class="text-2xl font-semibold leading-tight text-gray-800">
{{ __('Followup') }}
</h2>
</x-slot>
<div class="py-12">
<div class="mx-auto px-4 sm:px-6 lg:px-8">
<!-- Removed max-w-7xl to allow the table to grow wider -->
<div class="bg-white shadow rounded-lg p-6">
{{-- <button id="show-chart" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Show
Discount Codes
Chart</button> --}}
<div class="overflow-x-auto rounded-lg">
<table id="orders-table"
class="hover row-border min-w-full divide-y divide-gray-500 shadow overflow-hidden border-b border-gray-500 sm:rounded-lg">
<thead class="bg-gray-200">
<tr>
<th scope="col" class="text-center uppercase" style="width: 100px;">
Order Number
</th>
<th scope="col" class="text-center uppercase" style="width: 150px;">
Customer Name
</th>
<th scope="col" class="text-center uppercase" style="width: 150px;">
Customer Phone
</th>
<th scope="col" class="text-center uppercase" style="width: 100px;">
City
</th>
<th scope="col" class="text-center uppercase" style="width: 150px;">
Order Date
</th>
<th scope="col" class="text-center uppercase" style="width: 100px;">
Discount Code
</th>
<th scope="col" class="text-center uppercase" style="width: 200px;">
Special Items
</th>
<th scope="col" class="text-center uppercase" style="width: 100px;">
FollowUp Date
</th>
<th scope="col" class="text-center uppercase" style="width: 100px;">
Contact Employee
</th>
<th scope="col" class="text-center uppercase" style="width: 100px;">
Customer Responded ?
</th>
<th scope="col" class="text-center uppercase" style="width: 100px;">
Custome Note
</th>
<th scope="col" class="text-center uppercase" style="width: 100px;">
Routine Satisfaction
</th>
<th scope="col" class="text-center uppercase" style="width: 100px;">
Problem Reason
</th>
<th scope="col" class="text-center uppercase" style="width: 100px;">
Problem Solution
</th>
<th scope="col" class="text-center uppercase" style="width: 100px;">
Different Number Repeat
</th>
<th scope="col" class="text-center uppercase" style="width: 100px;">
Repeat After FollowUp
</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
</x-app-layout>
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.7/css/jquery.dataTables.min.css">
<link rel="stylesheet" href="https://cdn.datatables.net/buttons/2.4.2/css/buttons.dataTables.min.css">
<link rel="stylesheet" href="https://cdn.datatables.net/fixedheader/3.1.9/css/fixedHeader.dataTables.min.css">
<link rel="stylesheet" href="https://cdn.datatables.net/responsive/2.2.9/css/responsive.dataTables.min.css">
<link rel="stylesheet" href="https://cdn.datatables.net/searchbuilder/1.6.0/css/searchBuilder.dataTables.min.css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
<script src="https://cdn.datatables.net/1.13.7/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/buttons/2.4.2/js/dataTables.buttons.min.js"></script>
<script src="https://cdn.datatables.net/buttons/2.4.2/js/buttons.colVis.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
<script src="https://cdn.datatables.net/buttons/2.4.2/js/buttons.html5.min.js"></script>
<script src="https://cdn.datatables.net/buttons/2.4.2/js/buttons.print.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/pdfmake.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/vfs_fonts.js"></script>
<script src="https://cdn.datatables.net/fixedheader/3.1.9/js/dataTables.fixedHeader.min.js"></script>
<script src="https://cdn.datatables.net/responsive/2.2.9/js/dataTables.responsive.min.js"></script>
<script src="https://cdn.datatables.net/searchbuilder/1.6.0/js/dataTables.searchBuilder.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<!-- Initialize DataTables -->
<script>
$(document).ready(function() {
var table = $('#orders-table').DataTable({
processing: true,
serverSide: true,
// fixedHeader: true,
// responsive: true,
scrollX: true,
ajax: {
url: "{{ route('orders.followup-data') }}",
data: function(d) {
d.startDate = $('#start-date').val();
d.endDate = $('#end-date').val();
d.selectedColumn = $('#column-select').val();
}
},
columns: [{
data: 'order_number',
name: 'order_number'
},
{
data: 'customer_name',
name: 'customer_name'
},
{
data: 'customer_phone',
name: 'customer_phone'
},
{
data: 'city',
name: 'city'
},
{
data: 'order_date',
name: 'order_date'
},
{
data: 'discount_code',
name: 'discount_code'
},
{
data: 'special_items',
name: 'special_items'
},
{
data: 'follow_up_date',
name: 'follow_up_date'
},
{
data: 'contact_employee',
name: 'contact_employee',
render: function(data, type, row) {
return `
<select class="contact_employee-dropdown w-40 rounded-lg bg-gray-50 border border-gray-300 text-gray-700 py-2 px-4 leading-tight focus:outline-none focus:bg-white focus:border-blue-500" data-id="${row.id}" style="font-size: 14px;">
<option value="">Select Employee</option>
<option value="manar" ${data === 'manar' ? 'selected' : ''}>Manar</option>
<option value="hiba" ${data === 'hiba' ? 'selected' : ''}>Hiba</option>
<option value="ranim" ${data === 'ranim' ? 'selected' : ''}>Ranim</option>
<option value="marwa" ${data === 'marwa' ? 'selected' : ''}>Marwa</option>
</select>
`;
}
},
{
data: 'customer_responded',
name: 'customer_responded',
render: function(data, type, row) {
return `
<select class="customer_responded-dropdown w-40 rounded-lg bg-gray-50 border border-gray-300 text-gray-700 py-2 px-4 leading-tight focus:outline-none focus:bg-white focus:border-blue-500" data-id="${row.id}" style="font-size: 14px;">
<option value="">Select an option</option>
<option value="yes" ${data === 'yes' ? 'selected' : ''}>Yes</option>
<option value="no" ${data === 'no' ? 'selected' : ''}>No</option>
</select>
`;
}
},
{
data: 'action',
name: 'action',
orderable: false,
searchable: false,
render: function(data, type, row) {
return `
<button class="edit-modal-button bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" data-id="${row.id}" onclick="openModal(${row.id})">Edit</button>
`;
}
},
{
data: 'routine_satisfaction',
name: 'routine_satisfaction',
render: function(data, type, row) {
return `
<select class="routine_satisfaction-dropdown w-40 rounded-lg bg-gray-50 border border-gray-300 text-gray-700 py-2 px-4 leading-tight focus:outline-none focus:bg-white focus:border-blue-500" data-id="${row.id}" style="font-size: 14px;">
<option value="">Satisfaction Level</option>
<option value="bad" ${data === 'bad' ? 'selected' : ''}>Bad</option>
<option value="good" ${data === 'good' ? 'selected' : ''}>Good</option>
<option value="perfect" ${data === 'perfect' ? 'selected' : ''}>Perfect</option>
</select>
`;
}
},
{
data: 'problem_reason',
name: 'problem_reason',
render: function(data, type, row) {
return `
<select class="problem_reason-dropdown w-40 rounded-lg bg-gray-50 border border-gray-300 text-gray-700 py-2 px-4 leading-tight focus:outline-none focus:bg-white focus:border-blue-500" data-id="${row.id}" style="font-size: 14px;">
<option value="">Select a reason</option>
<option value="allergy_from_product" ${data === 'allergy_from_product' ? 'selected' : ''}>Allergy From Product</option>
<option value="not_enough_routine" ${data === 'not_enough_routine' ? 'selected' : ''}>Not Enough Routine</option>
<option value="wrong_usage" ${data === 'wrong_usage' ? 'selected' : ''}>Wrong Usage</option>
<option value="lack_of_commitment" ${data === 'lack_of_commitment' ? 'selected' : ''}>Lack Of Commitment</option>
<option value="wrong_routine" ${data === 'wrong_routine' ? 'selected' : ''}>Wrong Routine</option>
</select>
`;
}
},
{
data: 'problem_solution',
name: 'problem_solution',
render: function(data, type, row) {
return `<button onclick="openProblemSolutionModal(${row.id}, '${data}')" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Edit</button>`;
}
},
{
data: 'different_number_repeat',
name: 'different_number_repeat',
render: function(data, type, row) {
return `
<select class="different_number_repeat-dropdown w-40 rounded-lg bg-gray-50 border border-gray-300 text-gray-700 py-2 px-4 leading-tight focus:outline-none focus:bg-white focus:border-blue-500" data-id="${row.id}" style="font-size: 14px;">
<option value="">Select an option</option>
<option value="yes" ${data === 'yes' ? 'selected' : ''}>Yes</option>
<option value="no" ${data === 'no' ? 'selected' : ''}>No</option>
</select>
`;
}
},
{
data: 'repeat_after_follow_up',
name: 'repeat_after_follow_up',
render: function(data, type, row) {
return `
<select class="repeat_after_follow_up-dropdown w-40 rounded-lg bg-gray-50 border border-gray-300 text-gray-700 py-2 px-4 leading-tight focus:outline-none focus:bg-white focus:border-blue-500" data-id="${row.id}" style="font-size: 14px;">
<option value="">Select an option</option>
<option value="yes" ${data === 'yes' ? 'selected' : ''}>Yes</option>
<option value="no" ${data === 'no' ? 'selected' : ''}>No</option>
</select>
`;
}
},
],
dom: "<'row'<'col-sm-12 col-md-6'B><'col-sm-12 col-md-6'f>>" +
"<'row'<'col-sm-12'tr>>" +
"<'row'<'col-sm-12 col-md-4'l><'col-sm-12 col-md-4'i><'col-sm-12 col-md-4'p>>",
buttons: [{
extend: 'collection',
text: 'Export',
className: 'bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded',
buttons: [
'copy',
'csv',
'excel',
'pdf',
'print',
]
},
{
extend: 'colvis',
className: 'bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded',
text: 'Column visibility'
},
{
text: 'Filters',
className: 'bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded',
action: function(e, dt, node, config) {
openFilterModal();
}
}
],
});
// Custom event listener for opening the column visibility dropdown
table.on('buttons-action', function(e, buttonApi, dataTable, node, config) {
// Check if the button that triggered the action is ColVis
if (config.className.indexOf('colvis') !== -1) {
// Wait until the dropdown is actually created
setTimeout(function() {
// Apply max height and overflow to the dropdown for scrolling
$('.dt-button-collection').css({
'max-height': '200px', // or 'max-h-60' in Tailwind (Tailwind's max-h-60 class must be available in your CSS build)
'overflow-y': 'auto'
});
}, 50); // Adjust timeout if necessary
}
});
$(document).on('change', 'select', function() {
var orderId = $(this).data('id');
var column = $(this).attr('class').split('-')[0]; // Gets 'packaging', 'contact', etc.
var selectedValue = $(this).val();
// AJAX request to update the database
$.ajax({
url: '/orders/followup/update-field',
type: 'POST',
data: {
id: orderId,
field: column,
value: selectedValue,
_token: "{{ csrf_token() }}"
},
success: function(response) {
// Here, you'll check for the notify object in the response
if (response.notify) {
// Use the notification data to display a message
// This depends on how you're handling notifications client-side
// For example, if you're using toastr.js or another notification library:
toastr[response.notify.type](response.notify.message);
}
},
error: function(error) {
toastr['error']('An error occurred.');
}
});
});
$('#filter-button').on('click', function() {
table.ajax
.reload(); // This will make DataTables call the server again with the new parameters
});
// Trigger the DataTables re-query when the clear filter button is clicked
$('#clear-filter-button').on('click', function() {
$('#start-date').val('');
$('#end-date').val('');
$('#column-select').val('');
table.ajax.reload(); // This will clear the filters and reload the table
});
});
function openModal(id) {
// Use AJAX to fetch the current custom note
$.ajax({
url: `/followup/${id}/edit-custom-note`,
type: 'GET',
success: function(response) {
// Populate the modal input with the current custom note
$('#modal-input').val(response.custom_note);
$('#customNoteModal').data('id', id); // Store the ID in the modal for later use
$('#customNoteModal').show(); // Use the correct ID for the modal
},
error: function(error) {
console.log(error);
alert('Could not fetch the custom note');
}
});
}
function closeModal() {
$('#customNoteModal').hide(); // Use the correct ID for the modal
}
function saveChanges() {
var id = $('#customNoteModal').data('id'); // Retrieve the ID stored in the modal
var customNote = $('#modal-input').val(); // Get the updated custom note from the modal input
// Use AJAX to update the custom note
$.ajax({
url: `/followup/${id}/update-custom-note`,
type: 'POST',
data: {
custom_note: customNote,
_token: $('meta[name="csrf-token"]').attr('content'), // Include CSRF token
},
success: function(response) {
alert('Custom note updated successfully.');
$('#customNoteModal').hide(); // Use the correct ID for the modal
// Optionally, refresh the DataTable or specific part of your page to show the updated note
},
error: function(error) {
console.log(error);
alert('Failed to update the custom note.');
}
});
}
function openProblemSolutionModal(id) {
// Fetch the current problem solution before showing the modal
$.ajax({
url: `/followup/${id}/edit-problem-solution`,
type: 'GET',
success: function(response) {
$('#problemSolutionInput').val(response.problem_solution);
$('#problemSolutionModal').data('id', id).show();
},
error: function(error) {
alert('Could not fetch the problem solution.');
console.error(error);
}
});
}
function closeProblemSolutionModal() {
$('#problemSolutionModal').hide(); // Use jQuery for consistency and target the correct ID
}
function saveProblemSolutionChanges() {
var id = $('#problemSolutionModal').data('id');
var problemSolution = $('#problemSolutionInput').val();
$.ajax({
url: `/followup/${id}/update-problem-solution`,
type: 'POST',
data: {
problem_solution: problemSolution,
_token: $('meta[name="csrf-token"]').attr('content'),
},
success: function(response) {
alert('Problem solution updated successfully.');
$('#problemSolutionModal').hide();
// Optionally, refresh the DataTable or the specific row to reflect the updated data
},
error: function(error) {
alert('Failed to update the problem solution.');
console.error(error);
}
});
}
function closeChartModal() {
document.getElementById('chartModal').classList.add('hidden');
}
document.addEventListener('DOMContentLoaded', function() {
// This will ensure that the button element is available to attach the event listener
var closeButton = document.querySelector('#chartModal .bi-x')
.parentNode; // Get the parent button of the SVG
closeButton.addEventListener('click', closeChartModal);
});
</script>
<div id="chartModal" class="hidden fixed inset-0 z-50 overflow-y-auto bg-black bg-opacity-50">
<div class="flex items-center justify-center min-h-screen">
<div class="bg-white rounded-lg shadow-xl max-w-2xl mx-auto p-6"> <!-- Increased max-width -->
<div class="flex justify-between items-center"> <!-- Added items-center for vertical alignment -->
<h3 class="text-lg font-medium leading-6 text-gray-900">Discount Codes Chart</h3> <!-- Modal title -->
<button class="text-black hover:text-gray-700 p-2 rounded-md">
<!-- SVG for close button -->
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor"
class="bi bi-x" viewBox="0 0 16 16">
<path
d="M4.646 4.646a.5.5 0 011.768.708L6.707 6.707l3.647 3.647a.5.5 0 01-.708.708l-3.647-3.647L5.354 5.354a.5.5 0 01-.708-.708z" />
<path
d="M5.354 10.354a.5.5 0 00-.708.708l3.647 3.647 3.647-3.647a.5.5 0 00-.708-.708L6.707 6.707 5.354 5.354a.5.5 0 00-.708.708z" />
</svg>
</button>
</div>
<div class="mt-4 p-4"> <!-- Added padding -->
<canvas id="discountCodesChart" width="400" height="400"></canvas>
<!-- Specified width and height -->
</div>
</div>
</div>
</div>
<!-- Modal -->
<div id="customNoteModal" class="fixed z-10 inset-0 overflow-y-auto hidden" aria-labelledby="modal-title" role="dialog"
aria-modal="true">
<div class="flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<!-- Overlay -->
<div class="fixed inset-0 bg-gray-600 bg-opacity-50 transition-opacity" aria-hidden="true"></div>
<!-- Modal content -->
<div
class="inline-block align-middle bg-white rounded-2xl text-left overflow-hidden shadow-lg transform transition-all sm:max-w-lg sm:w-full">
<!-- Close button -->
<button type="button" onclick="closeModal()"
class="absolute top-2 right-2 text-gray-400 hover:text-gray-500 focus:outline-none focus:text-gray-500">
<svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12">
</path>
</svg>
</button>
<div class="bg-white px-6 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left w-full">
<h3 class="text-xl leading-6 font-semibold text-gray-900 mb-4" id="modal-title">Edit Custom
Note
</h3>
<!-- Modal Body -->
<div class="mt-2">
<!-- Form inputs here -->
<textarea type="text" id="modal-input"
class="form-textarea mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring focus:ring-indigo-500 focus:ring-opacity-50 text-lg py-3"
placeholder="Type your note here..."></textarea>
</div>
</div>
</div>
</div>
<div class="bg-gray-100 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
<button type="button" onclick="saveChanges()"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">Save</button>
<button type="button" onclick="closeModal()"
class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">Cancel</button>
</div>
</div>
</div>
</div>
<!-- Modal Structure (hidden by default) -->
<div id="addNotesModal" class="hidden fixed inset-0 z-50 overflow-y-auto bg-black bg-opacity-50">
<div class="flex items-center justify-center min-h-screen px-4 py-6">
<div class="w-full max-w-lg p-6 bg-white rounded-lg shadow-xl">
<div class="flex items-center justify-between mb-4">
<h3 class="text-xl font-semibold text-gray-900">Add Note</h3>
<button onclick="closeModal()" class="rounded hover:bg-gray-200 focus:outline-none">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"
xmlns="https://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M6 18L18 6M6 6l12 12">
</path>
</svg>
</button>
</div>
<div id="modal-content" class="space-y-4">
<!-- The modal content will be loaded dynamically with the form -->
</div>
<div class="flex justify-end pt-2 border-t">
<button onclick="closeModal()"
class="px-4 py-2 text-white bg-blue-500 rounded hover:bg-blue-700 focus:outline-none">Close</button>
</div>
</div>
</div>
</div>
<!-- Problem Solution Modal -->
<div id="problemSolutionModal" class="fixed inset-0 z-10 hidden overflow-y-auto" aria-labelledby="modal-title"
role="dialog" aria-modal="true">
<div class="flex items-end justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:block sm:p-0">
<div class="fixed inset-0 transition-opacity bg-gray-500 bg-opacity-75" aria-hidden="true"></div>
<div
class="inline-block overflow-hidden text-left align-bottom transition-all transform bg-white rounded-lg shadow-xl sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
<div class="px-4 pt-5 pb-4 bg-white sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div class="w-full mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<h3 class="text-lg font-medium leading-6 text-gray-900" id="modal-title">Edit Problem Solution
</h3>
<div class="mt-2">
<input type="text" id="problemSolutionInput"
class="w-full px-3 py-2 mt-1 text-lg leading-tight text-gray-700 border rounded shadow appearance-none focus:outline-none focus:shadow-outline"
placeholder="Enter problem solution">
</div>
</div>
</div>
</div>
<div class="px-4 py-3 bg-gray-50 sm:px-6 sm:flex sm:flex-row-reverse">
<button type="button" onclick="saveProblemSolutionChanges()"
class="inline-flex justify-center w-full px-4 py-2 text-base font-medium text-white bg-blue-600 border border-transparent rounded-md shadow-sm hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">Save</button>
<button type="button" onclick="$('#problemSolutionModal').hide()"
class="inline-flex justify-center w-full px-4 py-2 mt-3 text-base font-medium text-gray-700 bg-white border border-gray-300 rounded-md shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">Cancel</button>
</div>
</div>
</div>
</div>
<div id="filterModal" class="hidden fixed inset-0 z-50 overflow-y-auto bg-black bg-opacity-50">
<div class="flex items-center justify-center min-h-screen">
<div class="bg-white rounded-lg shadow-xl max-w-lg mx-auto p-6">
<div class="flex justify-end">
<button onclick="closeFilterModal()" class="text-black hover:text-gray-700">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"
xmlns="https://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M6 18L18 6M6 6l12 12">
</path>
</svg>
</button>
</div>
<div class="space-y-4">
<div>
<label for="start-date" class="block text-sm font-medium text-gray-700">Start Date:</label>
<input type="date" id="start-date" name="start-date"
class="mt-1 form-input block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50">
</div>
<div>
<label for="end-date" class="block text-sm font-medium text-gray-700">End Date:</label>
<input type="date" id="end-date" name="end-date"
class="mt-1 form-input block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50">
</div>
<div>
<label for="column-select" class="block text-sm font-medium text-gray-700">Select Column:</label>
<select id="column-select" name="column-select"
class="mt-1 form-select block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50">
<!-- Add options for column selection here -->
<option value="order_date">Order Date</option>
<option value="follow_up_date">FollowUp Date</option>
</select>
</div>
<div class="flex justify-between">
<button id="filter-button"
class="px-4 py-2 text-white bg-blue-500 rounded hover:bg-blue-700 focus:outline-none">Filter</button>
<button id="clear-filter-button"
class="px-4 py-2 text-white bg-red-500 rounded hover:bg-red-700 focus:outline-none">Clear
Filter</button>
</div>
</div>
</div>
</div>
</div>
<script>
function openFilterModal() {
// Code to display the filter modal
document.getElementById('filterModal').classList.remove('hidden');
}
function closeFilterModal() {
document.getElementById('filterModal').classList.add('hidden');
}
</script>
<script>
// Configure toastr options
toastr.options = {
"closeButton": true, // Show close button
"debug": false,
"newestOnTop": false,
"progressBar": true, // Show progress bar
"positionClass": "toast-top-right", // Position
"preventDuplicates": false,
"onclick": null,
"showDuration": "300",
"hideDuration": "1000",
"timeOut": "5000", // How long the toast will display without user interaction
"extendedTimeOut": "1000",
"showEasing": "swing",
"hideEasing": "linear",
"showMethod": "fadeIn",
"hideMethod": "fadeOut"
};
</script>
<style>
.dataTables_length {
margin-top: 20px;
}
.dataTables_length select {
padding: .375rem 1.75rem .375rem .75rem;
width: 60px;
font-size: 1rem;
line-height: 1.5;
border-radius: .25rem;
border: 1px solid #ced4da;
}
.dataTables_info {
float: right;
margin-left: 1rem;
font-size: 1rem;
}
.dataTables_wrapper .row {
clear: both;
}
</style>
and this is my controller
class FollowUpController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
return view('followup');
}
public function getOrdersData(Request $request)
{
$orders = Follow_Up::query();
if ($request->startDate && $request->endDate && $request->selectedColumn) {
$orders->whereBetween($request->selectedColumn, [$request->startDate, $request->endDate]);
}
return DataTables::of($orders)
// If you need to add additional columns or modify the data, you can do it here
->make(true);
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*/
public function show(Follow_Up $follow_Up)
{
//
}
/**
* Show the form for editing the specified resource.
*/
public function edit(Follow_Up $follow_Up)
{
//
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, Follow_Up $follow_Up)
{
$orderId = $request->id;
$field = $request->field;
$value = $request->value;
$order = Follow_Up::findOrFail($orderId);
if (in_array($field, ['contact_employee', 'customer_responded', 'routine_satisfaction', 'problem_reason', 'problem_solution', 'different_number_repeat', 'repeat_after_follow_up'])) {
$order->{$field} = $value;
$order->save();
// Assuming you want to use a success notification
$message = ucfirst($field) . ' updated successfully.';
// notify()->success($message);
return response()->json(['message' => $message, 'notify' => ['type' => 'success', 'message' => $message]]);
}
return response()->json(['message' => 'Invalid field.'], 400); // Bad request
}
public function editCustomNote($id)
{
$followUp = Follow_Up::findOrFail($id);
return response()->json(['custom_note' => $followUp->custom_note]);
}
public function updateCustomNote(Request $request, $id)
{
$request->validate([
'custom_note' => 'required|string', // Validate as per your requirement
]);
$followUp = Follow_Up::findOrFail($id);
$followUp->custom_note = $request->custom_note;
$followUp->save();
return response()->json(['message' => 'Custom note updated successfully.']);
}
public function editProblemSolution($id)
{
$followUp = Follow_Up::findOrFail($id);
return response()->json(['problem_solution' => $followUp->problem_solution]);
}
public function updateProblemSolution(Request $request, $id)
{
$request->validate(['problem_solution' => 'required|string']);
$followUp = Follow_Up::findOrFail($id);
$followUp->problem_solution = $request->problem_solution;
$followUp->save();
return response()->json(['message' => 'Problem solution updated successfully.']);
}
public function getDiscountCodesData()
{
$data = Follow_Up::select('discount_code', DB::raw('count(*) as total'))
->groupBy('discount_code')
->get();
return response()->json($data);
}
/**
* Remove the specified resource from storage.
*/
public function destroy(Follow_Up $follow_Up)
{
//
}
}
and this is my routes
Route::get('/follow-up', [FollowUpController::class, 'index'])->name('followup_dashboard');
Route::get('/orders/followup-data', [FollowUpController::class, 'getOrdersData'])->name('orders.followup-data');
Route::post('/orders/followup/update-field', [FollowUpController::class, 'update'])->name('orders.followup.update-field');
Route::get('/followup/{id}/edit-custom-note', [FollowUpController::class, 'editCustomNote'])->name('followup.editCustomNote');
Route::post('/followup/{id}/update-custom-note', [FollowUpController::class, 'updateCustomNote'])->name('followup.updateCustomNote');
Route::get('/followup/{id}/edit-problem-solution', [FollowUpController::class, 'editProblemSolution'])->name('followup.editProblemSolution');
Route::post('/followup/{id}/update-problem-solution', [FollowUpController::class, 'updateProblemSolution'])->name('followup.updateProblemSolution');
Route::post('/followup/filter-data', [FollowUpController::class, 'filterData'])->name('filter.followup-data');
Route::get('/followup/discount-codes-data', [FollowUpController::class, 'getDiscountCodesData'])->name('followup.chart.data');
Please or to participate in this conversation.