Add search functionality to product listing and enable custom title editing

This commit is contained in:
2024-12-16 23:36:09 +01:00
parent 03a6d68c62
commit 730ff661c8
5 changed files with 173 additions and 11 deletions

View File

@@ -35,8 +35,8 @@
},
"class.Products.php": {
"type": "-",
"size": 5528,
"lmtime": 1733868220485,
"size": 6164,
"lmtime": 1734294911481,
"modified": false
},
"class.Site.php": {
@@ -103,7 +103,32 @@
"lmtime": 1733867176273,
"modified": false
},
"layout": {},
"layout": {
"favicon.png": {
"type": "-",
"size": 353,
"lmtime": 0,
"modified": false
},
"style.css": {
"type": "-",
"size": 18209,
"lmtime": 1734294926103,
"modified": false
},
"style.css.map": {
"type": "-",
"size": 32843,
"lmtime": 1734294926103,
"modified": false
},
"style.scss": {
"type": "-",
"size": 22785,
"lmtime": 1734294925955,
"modified": false
}
},
"libraries": {
"bootstrap": {},
"bootstrap-4.1.3": {},

View File

@@ -16,9 +16,10 @@ class Products
$start = \S::get( 'start' ) ? \S::get( 'start' ) : 0;
$order_dir = \S::get( 'order[0][dir]' ) ? strtoupper( \S::get( 'order[0][dir]' ) ) : 'DESC';
$order_name = \S::get( 'order[0][name]' ) ? \S::get( 'order[0][name]' ) : 'clicks';
$search = $_POST['search']['value'];
$db_results = \factory\Products::get_products( $client_id, $limit, $start, $order_name, $order_dir );
$recordsTotal = \factory\Products::get_records_total_products( $client_id );
$db_results = \factory\Products::get_products( $client_id, $search, $limit, $start, $order_name, $order_dir );
$recordsTotal = \factory\Products::get_records_total_products( $client_id, $search );
$data['draw'] = \S::get( 'draw' );
$data['recordsTotal'] = $recordsTotal;
@@ -38,11 +39,12 @@ class Products
$data['data'][] = [
$row['product_id'],
'<div class="table-product-title">
$row['offer_id'],
'<div class="table-product-title" product_id="' . $row['product_id'] . '">
<a href="/products/product_history/client_id=' . $client_id . '&product_id=' . $row['product_id'] . '" target="_blank" class="' . $custom_class . '">
' . $row['name'] . '
</a>
<span class="edit-product-title" offer-id="' . $row['product_id'] . '">
<span class="edit-product-title" product_id="' . $row['product_id'] . '">
<i class="fa fa-pencil"></i>
</span>
</div>',
@@ -195,4 +197,19 @@ class Products
]);
exit;
}
static public function save_custom_title()
{
$product_id = \S::get( 'product_id' );
$custom_title = \S::get( 'custom_title' );
if ( \factory\Products::set_product_data( $product_id, 'title', $custom_title ) )
{
\factory\Products::add_product_comment( $product_id, 1, 'Zmiana nazwy produktu na: ' . $custom_title );
echo json_encode( [ 'status' => 'ok' ] );
}
else
echo json_encode( [ 'status' => 'error' ] );
exit;
}
}

View File

@@ -2,16 +2,24 @@
namespace factory;
class Products
{
static public function get_products( $client_id, $limit, $start, $order_name, $order_dir )
static public function get_products( $client_id, $search, $limit, $start, $order_name, $order_dir )
{
global $mdb;
return $mdb -> query( 'SELECT pt.*, p.offer_id FROM products_temp AS pt INNER JOIN products AS p ON p.id = pt.product_id WHERE client_id = \'' . $client_id . '\' ORDER BY ' . $order_name . ' ' . $order_dir . ' LIMIT ' . $start . ', ' . $limit ) -> fetchAll();
if ( $search )
return $mdb -> query( 'SELECT pt.*, p.offer_id FROM products_temp AS pt INNER JOIN products AS p ON p.id = pt.product_id WHERE client_id = \'' . $client_id . '\' AND pt.name LIKE \'%' . $search . '%\' ORDER BY ' . $order_name . ' ' . $order_dir . ' LIMIT ' . $start . ', ' . $limit ) -> fetchAll();
else
return $mdb -> query( 'SELECT pt.*, p.offer_id FROM products_temp AS pt INNER JOIN products AS p ON p.id = pt.product_id WHERE client_id = \'' . $client_id . '\' ORDER BY ' . $order_name . ' ' . $order_dir . ' LIMIT ' . $start . ', ' . $limit ) -> fetchAll();
}
static public function get_records_total_products( $client_id )
static public function get_records_total_products( $client_id, $search )
{
global $mdb;
return $mdb -> query( 'SELECT COUNT(0) FROM products_temp AS pt INNER JOIN products AS p ON p.id = pt.product_id WHERE client_id = \'' . $client_id . '\'' ) -> fetchColumn();
if ( $search )
return $mdb -> query( 'SELECT COUNT(0) FROM products_temp AS pt INNER JOIN products AS p ON p.id = pt.product_id WHERE client_id = \'' . $client_id . '\' AND pt.name LIKE \'%' . $search . '%\'' ) -> fetchColumn();
else
return $mdb -> query( 'SELECT COUNT(0) FROM products_temp AS pt INNER JOIN products AS p ON p.id = pt.product_id WHERE client_id = \'' . $client_id . '\'' ) -> fetchColumn();
}
static public function get_product_data( $product_id, $field )

View File

@@ -56,6 +56,19 @@ function confirm_message( m_content, m_url )
});
}
function escapeHtml(str)
{
var map =
{
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#039;'
};
return str.replace(/[&<>"']/g, function(m) {return map[m];});
}
function get_elapsed_time_string(total_seconds)
{
function pretty_time_string(num)

View File

@@ -25,6 +25,7 @@
<thead>
<tr>
<th scope="col">Id</th>
<th scope="col">Id oferty</th>
<th scope="col">Nazwa produktu</th>
<th scope="col">Wyśw.</th>
<th scope="col">Wyśw. (30 dni)</th>
@@ -66,6 +67,7 @@
serverSide: true,
columns: [
{ width: '100px', orderable: false },
{ width: '100px', name: 'offer_id' },
{ width: 'auto', name: 'name' },
{ width: 'auto', name: 'impressions' },
{ width: 'auto', name: 'impressions_30' },
@@ -103,5 +105,102 @@
}
});
});
$( 'body' ).on( 'click', '.edit-product-title', function(e)
{
$.confirm({
title: 'Edytuj tytuł',
content: '' +
'<form action="" class="formName">' +
'<div class="form-group">' +
'<input type="text" value="' + escapeHtml( $( this ).siblings( 'a' ).text().trim() ) + '" product_id="' + $( this ).attr( 'product_id' ) + '" class="name form-control" required />' +
'<small>0/150 znaków</small>' +
'</div>' +
'</form>',
columnClass: 'col-md-8 col-md-offset-2 col-12',
theme: 'modern',
draggable: true,
buttons: {
formSubmit: {
text: 'Zapisz',
btnClass: 'btn-blue',
action: function () {
var jc = this;
var product_id = this.$content.find( '.name' ).attr( 'product_id' );
var customTitle = this.$content.find('.name').val();
if ( !customTitle )
{
$.alert('Pole tytuł nie może być puste!');
return false;
}
else if (customTitle.length > 150)
{
$.alert('Pole tytuł nie może przekraczać 150 znaków!');
this.$content.find('.name').addClass('is-invalid');
return false;
}
jc.showLoading(true);
$.ajax({
url: '/products/save_custom_title/',
type: 'POST',
data: {
product_id: product_id,
custom_title: customTitle
},
success: function(response) {
data = JSON.parse(response);
jc.hideLoading();
if ( data.status == 'ok' )
{
$.alert( 'Tytuł został pomyślnie zapisany' );
jc.close();
}
else
{
$.alert('Błąd: ' + response);
}
},
error: function() {
jc.hideLoading();
$.alert('Wystąpił błąd podczas zapisywania tytułu. Spróbuj ponownie.');
}
});
}
},
cancel: {
text: 'Anuluj',
btnClass: 'btn-red',
action: function () {
}
},
},
onContentReady: function () {
var jc = this;
var inputField = this.$content.find('.name');
var charCount = this.$content.find('small');
inputField.on('input', function() {
var currentLength = $(this).val().length;
charCount.text(currentLength + '/150 znaków');
if (currentLength > 150) {
$(this).addClass('is-invalid');
} else {
$(this).removeClass('is-invalid');
}
});
this.$content.find('form').on('submit', function (e) {
e.preventDefault();
jc.$$formSubmit.trigger('click');
});
}
});
});
});
</script>