Skip to content

Commit 19b809b

Browse files
committed
Added SortableJS Library, and updated Invoice, Quote and Recurring to use it. Added Grab Bar Icons next to action buttons. Will now sort in Mobile much more efficiently, update ajax vars for recurring invoice
1 parent 60fe02b commit 19b809b

File tree

6 files changed

+136
-152
lines changed

6 files changed

+136
-152
lines changed

ajax.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -586,13 +586,13 @@
586586
enforceUserPermission('module_sales', 2);
587587

588588
$positions = $_POST['positions'];
589-
$recurring_id = intval($_POST['recurring_id']);
589+
$recurring_invoice_id = intval($_POST['recurring_invoice_id']);
590590

591591
foreach ($positions as $position) {
592592
$id = intval($position['id']);
593593
$order = intval($position['order']);
594594

595-
mysqli_query($mysqli, "UPDATE invoice_items SET item_order = $order WHERE item_recurring_id = $recurring_id AND item_id = $id");
595+
mysqli_query($mysqli, "UPDATE invoice_items SET item_order = $order WHERE item_recurring_invoice_id = $recurring_invoice_id AND item_id = $id");
596596
}
597597

598598
// return a response

css/itflow_custom.css

+7-6
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@
2020
}
2121
}
2222

23-
.grab-cursor {
24-
cursor: grab;
25-
}
26-
27-
.grab-cursor:active {
28-
cursor: grabbing;
23+
button.drag-handle {
24+
cursor: grab !important;
25+
touch-action: none;
26+
user-select: none;
2927
}
28+
button.drag-handle:active {
29+
cursor: grabbing !important;
30+
}

invoice.php

+41-47
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@
165165

166166

167167
?>
168+
168169
<link rel="stylesheet" href="plugins/dragula/dragula.min.css">
169170

170171
<ol class="breadcrumb d-print-none">
@@ -381,26 +382,34 @@
381382
<tr data-item-id="<?php echo $item_id; ?>">
382383
<td class="d-print-none">
383384
<?php if ($invoice_status !== "Paid" && $invoice_status !== "Cancelled") { ?>
384-
<div class="dropdown">
385-
<button class="btn btn-sm btn-light" type="button" data-toggle="dropdown">
386-
<i class="fas fa-ellipsis-v"></i>
387-
</button>
388-
<div class="dropdown-menu">
389-
<a class="dropdown-item" href="#"
390-
data-toggle="ajax-modal"
391-
data-ajax-url="ajax/ajax_item_edit.php"
392-
data-ajax-id="<?php echo $item_id; ?>"
393-
>
394-
<i class="fa fa-fw fa-edit mr-2"></i>Edit
395-
</a>
396-
<div class="dropdown-divider"></div>
397-
<a class="dropdown-item text-danger confirm-link" href="post.php?delete_invoice_item=<?php echo $item_id; ?>"><i class="fa fa-fw fa-trash mr-2"></i>Delete</a>
385+
<div class="row">
386+
<div class="col">
387+
<button type="button" class="btn btn-sm btn-light drag-handle">
388+
<i class="fas fa-bars text-muted"></i>
389+
</button>
390+
</div>
391+
<div class="col">
392+
<div class="dropdown">
393+
<button class="btn btn-sm btn-light" type="button" data-toggle="dropdown">
394+
<i class="fas fa-ellipsis-v"></i>
395+
</button>
396+
<div class="dropdown-menu">
397+
<a class="dropdown-item" href="#"
398+
data-toggle="ajax-modal"
399+
data-ajax-url="ajax/ajax_item_edit.php"
400+
data-ajax-id="<?php echo $item_id; ?>"
401+
>
402+
<i class="fa fa-fw fa-edit mr-2"></i>Edit
403+
</a>
404+
<div class="dropdown-divider"></div>
405+
<a class="dropdown-item text-danger confirm-link" href="post.php?delete_invoice_item=<?php echo $item_id; ?>"><i class="fa fa-fw fa-trash mr-2"></i>Delete</a>
406+
</div>
407+
</div>
398408
</div>
399409
</div>
400-
401410
<?php } ?>
402411
</td>
403-
<td class="grab-cursor"><?php echo $item_name; ?></td>
412+
<td><?php echo $item_name; ?></td>
404413
<td><?php echo nl2br($item_description); ?></td>
405414
<td class="text-center"><?php echo number_format($item_quantity, 2); ?></td>
406415
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $item_price, $invoice_currency_code); ?></td>
@@ -1178,38 +1187,23 @@
11781187
}
11791188
</script>
11801189

1181-
<script src="plugins/dragula/dragula.min.js"></script>
1190+
<script src="plugins/SortableJS/Sortable.min.js"></script>
11821191
<script>
1183-
$(document).ready(function() {
1184-
var container = $('table#items tbody')[0];
1185-
1186-
dragula([container])
1187-
.on('drop', function (el, target, source, sibling) {
1188-
// Handle the drop event to update the order in the database
1189-
var rows = $(container).children();
1190-
var positions = rows.map(function(index, row) {
1191-
return {
1192-
id: $(row).data('itemId'),
1193-
order: index
1194-
};
1195-
}).get();
1196-
1197-
// Send the new order to the server
1198-
$.ajax({
1199-
url: 'ajax.php',
1200-
method: 'POST',
1201-
data: {
1202-
update_invoice_items_order: true,
1203-
invoice_id: <?php echo $invoice_id; ?>,
1204-
positions: positions
1205-
},
1206-
success: function(data) {
1207-
// Handle success
1208-
},
1209-
error: function(error) {
1210-
console.error('Error updating order:', error);
1211-
}
1212-
});
1192+
new Sortable(document.querySelector('table#items tbody'), {
1193+
handle: '.drag-handle',
1194+
animation: 150,
1195+
onEnd: function (evt) {
1196+
const rows = document.querySelectorAll('table#items tbody tr');
1197+
const positions = Array.from(rows).map((row, index) => ({
1198+
id: row.dataset.itemId,
1199+
order: index
1200+
}));
1201+
1202+
$.post('ajax.php', {
1203+
update_invoice_items_order: true,
1204+
invoice_id: <?php echo $invoice_id; ?>,
1205+
positions: positions
12131206
});
1207+
}
12141208
});
12151209
</script>

plugins/SortableJS/Sortable.min.js

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

quote.php

+43-48
Original file line numberDiff line numberDiff line change
@@ -326,27 +326,37 @@
326326
<tr data-item-id="<?php echo $item_id; ?>">
327327
<td class="d-print-none">
328328
<?php if ($quote_status !== "Invoiced" && $quote_status !== "Accepted" && $quote_status !== "Declined" && lookupUserPermission("module_sales") >= 2) { ?>
329-
<div class="dropdown">
330-
<button class="btn btn-sm btn-light" type="button" data-toggle="dropdown">
331-
<i class="fas fa-ellipsis-v"></i>
332-
</button>
333-
<div class="dropdown-menu">
334-
<a class="dropdown-item" href="#"
335-
data-toggle="ajax-modal"
336-
data-ajax-url="ajax/ajax_item_edit.php"
337-
data-ajax-id="<?php echo $item_id; ?>"
338-
>
339-
<i class="fa fa-fw fa-edit mr-2"></i>Edit
340-
</a>
341-
<div class="dropdown-divider"></div>
342-
<a class="dropdown-item text-danger confirm-link" href="post.php?delete_quote_item=<?php echo $item_id; ?>">
343-
<i class="fa fa-fw fa-trash mr-2"></i>Delete
344-
</a>
329+
<div class="row">
330+
<div class="col">
331+
<button type="button" class="btn btn-sm btn-light drag-handle">
332+
<i class="fas fa-bars text-muted"></i>
333+
</button>
334+
</div>
335+
<div class="col">
336+
337+
<div class="dropdown">
338+
<button class="btn btn-sm btn-light" type="button" data-toggle="dropdown">
339+
<i class="fas fa-ellipsis-v"></i>
340+
</button>
341+
<div class="dropdown-menu">
342+
<a class="dropdown-item" href="#"
343+
data-toggle="ajax-modal"
344+
data-ajax-url="ajax/ajax_item_edit.php"
345+
data-ajax-id="<?php echo $item_id; ?>"
346+
>
347+
<i class="fa fa-fw fa-edit mr-2"></i>Edit
348+
</a>
349+
<div class="dropdown-divider"></div>
350+
<a class="dropdown-item text-danger confirm-link" href="post.php?delete_quote_item=<?php echo $item_id; ?>">
351+
<i class="fa fa-fw fa-trash mr-2"></i>Delete
352+
</a>
353+
</div>
354+
</div>
345355
</div>
346356
</div>
347357
<?php } ?>
348358
</td>
349-
<td class="grab-cursor"><?php echo $item_name; ?></td>
359+
<td><?php echo $item_name; ?></td>
350360
<td><?php echo nl2br($item_description); ?></td>
351361
<td class="text-center"><?php echo number_format($item_quantity, 2); ?></td>
352362
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $item_price, $quote_currency_code); ?></td>
@@ -992,38 +1002,23 @@
9921002
}
9931003
</script>
9941004

995-
<script src="plugins/dragula/dragula.min.js"></script>
1005+
<script src="plugins/SortableJS/Sortable.min.js"></script>
9961006
<script>
997-
$(document).ready(function() {
998-
var container = $('table#items tbody')[0];
999-
1000-
dragula([container])
1001-
.on('drop', function (el, target, source, sibling) {
1002-
// Handle the drop event to update the order in the database
1003-
var rows = $(container).children();
1004-
var positions = rows.map(function(index, row) {
1005-
return {
1006-
id: $(row).data('itemId'),
1007-
order: index
1008-
};
1009-
}).get();
1010-
1011-
// Send the new order to the server
1012-
$.ajax({
1013-
url: 'ajax.php',
1014-
method: 'POST',
1015-
data: {
1016-
update_quote_items_order: true,
1017-
quote_id: <?php echo $quote_id; ?>,
1018-
positions: positions
1019-
},
1020-
success: function(data) {
1021-
// Handle success
1022-
},
1023-
error: function(error) {
1024-
console.error('Error updating order:', error);
1025-
}
1026-
});
1007+
new Sortable(document.querySelector('table#items tbody'), {
1008+
handle: '.drag-handle',
1009+
animation: 150,
1010+
onEnd: function (evt) {
1011+
const rows = document.querySelectorAll('table#items tbody tr');
1012+
const positions = Array.from(rows).map((row, index) => ({
1013+
id: row.dataset.itemId,
1014+
order: index
1015+
}));
1016+
1017+
$.post('ajax.php', {
1018+
update_quote_items_order: true,
1019+
quote_id: <?php echo $quote_id; ?>,
1020+
positions: positions
10271021
});
1022+
}
10281023
});
10291024
</script>

0 commit comments

Comments
 (0)