Paginazione select2

This commit is contained in:
Thomas Zilio 2019-02-22 10:37:37 +01:00
parent 389865a68a
commit af428c6058
11 changed files with 236 additions and 98 deletions

View File

@ -2,6 +2,8 @@
include_once __DIR__.'/core.php';
use Util\Query;
// Informazioni fondamentali
$columns = filter('columns');
$order = filter('order')[0];
@ -32,27 +34,23 @@ $results = [
'summable' => [],
];
$query = Util\Query::getQuery($structure);
$query = Query::getQuery($structure);
if (!empty($query)) {
// CONTEGGIO TOTALE
$results['recordsTotal'] = $dbo->fetchNum($query);
// RISULTATI VISIBILI
$query = Util\Query::getQuery($structure, $search, $order, $limit);
$query = Query::getQuery($structure, $search, $order, $limit);
// Filtri derivanti dai permessi (eventuali)
if (empty($id_plugin)) {
$query = Modules::replaceAdditionals($id_module, $query);
}
$query = str_replace_once('SELECT', 'SELECT SQL_CALC_FOUND_ROWS', $query);
$rows = $dbo->fetchArray($query);
// Conteggio dei record filtrati
$count = $dbo->fetchArray('SELECT FOUND_ROWS()');
if (!empty($count)) {
$results['recordsFiltered'] = $count[0]['FOUND_ROWS()'];
}
$data = Query::executeAndCount($query);
$rows = $data['results'];
$results['recordsFiltered'] = $data['count'];
// SOMME
$results['summable'] = Util\Query::getSums($structure, $search);

View File

@ -4,14 +4,16 @@ include_once __DIR__.'/core.php';
if (!isset($resource)) {
$op = empty($op) ? filter('op') : $op;
$search = filter('q');
$search = filter('search');
$page = filter('page') ?: 0;
$length = filter('length') ?: 100;
if (!isset($elements)) {
$elements = [];
}
$elements = (!is_array($elements)) ? explode(',', $elements) : $elements;
$results = AJAX::select($op, $elements, $search);
$results = AJAX::select($op, $elements, $search, $page, $length);
echo json_encode($results);
}

View File

@ -972,13 +972,23 @@ function start_superselect() {
delay: 250,
data: function (params) {
return {
q: params.term // search term
search: params.term,
page: params.page || 0,
length: params.length || 100,
}
},
processResults: function (data) {
return {
results: data
}
processResults: function (data, params) {
params.page = params.page || 0;
params.length = params.length || 100;
var response = {
results: data.results,
pagination: {
more: (params.page + 1) * params.length < data.recordsFiltered,
}
};
return response;
},
cache: false
},

View File

@ -175,3 +175,60 @@ function logger()
{
return Monolog\Registry::getInstance('logs');
}
/**
* Restituisce il numero indicato formattato secondo la configurazione del sistema.
*
* @param float $number
* @param int $decimals
*
* @return string
*
* @since 2.4.8
*/
function numberFormat($number, $decimals)
{
return Translator::numberToLocale($number, $decimals);
}
/**
* Restituisce il timestamp indicato formattato secondo la configurazione del sistema.
*
* @param string $timestamp
+ *
* @return string
*
* @since 2.4.8
*/
function timestampFormat($timestamp)
{
return Translator::timestampToLocale($timestamp);
}
/**
* Restituisce la data indicata formattato secondo la configurazione del sistema.
*
* @param string $date
*
* @return string
*
* @since 2.4.8
*/
function dateFormat($date)
{
return Translator::dateToLocale($date);
}
/**
* Restituisce l'orario indicato formattato secondo la configurazione del sistema.
*
* @param string $time
*
* @return string
*
* @since 2.4.8
*/
function timeFormat($time)
{
return Translator::timeToLocale($time);
}

View File

@ -77,30 +77,6 @@ if (!function_exists('ends_with')) {
}
}
if (!function_exists('str_replace_once')) {
/**
* Sostituisce la prima occorenza di una determinata stringa.
*
* @param string $str_pattern
* @param string $str_replacement
* @param string $string
*
* @since 2.3
*
* @return string
*/
function str_replace_once($str_pattern, $str_replacement, $string)
{
if (strpos($string, $str_pattern) !== false) {
$occurrence = strpos($string, $str_pattern);
return substr_replace($string, $str_replacement, strpos($string, $str_pattern), strlen($str_pattern));
}
return $string;
}
}
if (!function_exists('str_contains')) {
/**
* Check if a string contains the given string.

View File

@ -87,7 +87,7 @@ switch ($resource) {
$search_fields[] = 'provincia LIKE '.prepare('%'.$search.'%');
}
$results = AJAX::completeResults($query, $where, $filter, $search, $custom);
$results = AJAX::selectResults($query, $where, $filter, $search, $limit, $custom);
// Evidenzia l'agente di default
if ($superselect['idanagrafica']) {

View File

@ -4,7 +4,62 @@ include_once __DIR__.'/../../../core.php';
switch ($resource) {
case 'articoli':
$query = 'SELECT mg_articoli.*, (SELECT CONCAT(co_pianodeiconti2.numero, ".", co_pianodeiconti3.numero, " ", co_pianodeiconti3.descrizione) FROM co_pianodeiconti3 INNER JOIN co_pianodeiconti2 ON co_pianodeiconti3.idpianodeiconti2=co_pianodeiconti2.id WHERE co_pianodeiconti3.id = idconto_vendita) AS idconto_vendita_title, (SELECT CONCAT(co_pianodeiconti2.numero, ".", co_pianodeiconti3.numero, " ", co_pianodeiconti3.descrizione) FROM co_pianodeiconti3 INNER JOIN co_pianodeiconti2 ON co_pianodeiconti3.idpianodeiconti2=co_pianodeiconti2.id WHERE co_pianodeiconti3.id = idconto_acquisto) AS idconto_acquisto_title, co_iva.descrizione AS iva_vendita FROM mg_articoli LEFT OUTER JOIN co_iva ON mg_articoli.idiva_vendita=co_iva.id |where| ORDER BY mg_articoli.id_categoria ASC, mg_articoli.id_sottocategoria ASC';
$query = 'SELECT
mg_articoli.id,
mg_articoli.codice,
mg_articoli.descrizione,
mg_articoli.um,
mg_articoli.idiva_vendita,
mg_articoli.idconto_vendita,
mg_articoli.idconto_acquisto,
mg_articoli.prezzo_vendita,
mg_articoli.prezzo_acquisto,
categoria.`nome` AS categoria,
sottocategoria.`nome` AS sottocategoria,
co_iva.descrizione AS iva_vendita,
CONCAT(conto_vendita_categoria .numero, ".", conto_vendita_sottocategoria.numero, " ", conto_vendita_sottocategoria.descrizione) AS idconto_vendita_title,
CONCAT(conto_acquisto_categoria .numero, ".", conto_acquisto_sottocategoria.numero, " ", conto_acquisto_sottocategoria.descrizione) AS idconto_acquisto_title
FROM mg_articoli
LEFT JOIN co_iva ON mg_articoli.idiva_vendita = co_iva.id
LEFT JOIN `mg_categorie` AS categoria ON `categoria`.`id` = `mg_articoli`.`id_categoria`
LEFT JOIN `mg_categorie` AS sottocategoria ON `sottocategoria`.`id` = `mg_articoli`.`id_sottocategoria`
LEFT JOIN co_pianodeiconti3 AS conto_vendita_sottocategoria ON conto_vendita_sottocategoria.id=mg_articoli.idconto_vendita
LEFT JOIN co_pianodeiconti2 AS conto_vendita_categoria ON conto_vendita_sottocategoria.idpianodeiconti2=conto_vendita_categoria.id
LEFT JOIN co_pianodeiconti3 AS conto_acquisto_sottocategoria ON conto_acquisto_sottocategoria.id=mg_articoli.idconto_acquisto
LEFT JOIN co_pianodeiconti2 AS conto_acquisto_categoria ON conto_acquisto_sottocategoria.idpianodeiconti2=conto_acquisto_categoria.id
|where| ORDER BY mg_articoli.id_categoria ASC, mg_articoli.id_sottocategoria ASC';
foreach ($elements as $element) {
$filter[] = 'mg_articoli.id='.prepare($element);
}
$where[] = 'attivo = 1';
if (!empty($superselect['dir']) && $superselect['dir'] == 'entrata') {
//$where[] = '(qta > 0 OR servizio = 1)';
}
if (!empty($search)) {
$search_fields[] = 'mg_articoli.descrizione LIKE '.prepare('%'.$search.'%');
$search_fields[] = 'mg_articoli.codice LIKE '.prepare('%'.$search.'%');
}
$custom = [
'id' => 'id',
'codice' => 'codice',
'descrizione' => 'descrizione',
'um' => 'um',
'idiva_vendita' => 'idiva_vendita',
'iva_vendita' => 'iva_vendita',
'idconto_vendita' => 'idconto_vendita',
'idconto_vendita_title' => 'idconto_vendita_title',
'idconto_acquisto' => 'idconto_acquisto',
'idconto_acquisto_title' => 'idconto_acquisto_title',
'prezzo_acquisto' => 'prezzo_acquisto',
'prezzo_vendita' => 'prezzo_vendita',
];
$data = AJAX::selectResults($query, $where, $filter, $search_fields, $limit, $custom);
$rs = $data['results'];
// Individuazione di eventuali listini
if (!empty($superselect['dir']) && !empty($superselect['idanagrafica'])) {
@ -21,45 +76,22 @@ switch ($resource) {
$idiva_predefinita = get_var('Iva predefinita');
$iva_predefinita = $dbo->fetchOne('SELECT descrizione FROM co_iva WHERE id='.prepare($idiva_predefinita))['descrizione'];
foreach ($elements as $element) {
$filter[] = 'mg_articoli.id='.prepare($element);
}
$where[] = 'attivo = 1';
if (!empty($superselect['dir']) && $superselect['dir'] == 'entrata') {
//$where[] = '(qta > 0 OR servizio = 1)';
}
if (!empty($search)) {
$search_fields[] = 'mg_articoli.descrizione LIKE '.prepare('%'.$search.'%');
$search_fields[] = 'mg_articoli.codice LIKE '.prepare('%'.$search.'%');
}
if (!empty($search_fields)) {
$where[] = '('.implode(' OR ', $search_fields).')';
}
if (!empty($filter)) {
$where[] = '('.implode(' OR ', $filter).')';
}
$wh = '';
if (count($where) != 0) {
$wh = 'WHERE '.implode(' AND ', $where);
}
$query = str_replace('|where|', $wh, $query);
$prev = -1;
$rs = $dbo->fetchArray($query);
$previous_category = -1;
$previous_subcategory = -1;
foreach ($rs as $r) {
if ($prev != $r['id_sottocategoria']) {
$categoria = $dbo->fetchOne('SELECT `nome` FROM `mg_categorie` WHERE `id`='.prepare($r['id_categoria']))['nome'];
if ($previous_category != $r['categoria'] || $previous_subcategory != $r['sottocategoria']) {
$previous_category = $r['categoria'];
$previous_subcategory = $r['sottocategoria'];
$sottocategoria = $dbo->fetchOne('SELECT `nome` FROM `mg_categorie` WHERE `id`='.prepare($r['id_sottocategoria']));
$sottocategoria = isset($sottocategoria['nome']) ? $sottocategoria['nome'] : null;
$text = '<i>'.tr('Nessuna categoria').'</i>';
if (!empty($r['categoria'])) {
$text = $r['categoria'].' ('.(!empty($r['sottocategoria']) ? $r['sottocategoria'] : '-').')';
}
$prev = $r['id_sottocategoria'];
$results[] = ['text' => $categoria.' ('.(!empty($r['id_sottocategoria']) ? $sottocategoria : '-').')', 'children' => []];
$results[] = [
'text' => $text,
'children' => [],
];
}
// Iva dell'articolo
@ -101,6 +133,11 @@ switch ($resource) {
];
}
$results = [
'results' => $results,
'recordsFiltered' => $data['recordsFiltered'],
];
break;
case 'prodotti_lotti':

View File

@ -24,7 +24,7 @@ switch ($resource) {
$custom['contenuto'] = 'contenuto';
$results = AJAX::completeResults($query, $where, $filter, $search, $custom);
$results = AJAX::selectResults($query, $where, $filter, $search, $limit, $custom);
foreach ($results as $key => $value) {
$matricola = \Util\Ini::getValue($r['contenuto'], 'Matricola');

View File

@ -23,10 +23,12 @@ class AJAX
* @param string $resource
* @param array $elements
* @param mixed $search
* @param int $page
* @param int $length
*
* @return array
*/
public static function select($resource, $elements = [], $search = null)
public static function select($resource, $elements = [], $search = null, $page = 0, $length = 100)
{
if (!isset($elements)) {
$elements = [];
@ -39,13 +41,23 @@ class AJAX
array_unshift($files, DOCROOT.'/ajax_select.php');
foreach ($files as $file) {
$results = self::getSelectResults($file, $resource, $elements, $search);
$results = self::getSelectResults($file, $resource, $elements, [
'offset' => $page * $length,
'length' => $length,
], $search);
if (isset($results)) {
break;
}
}
return $results;
$total = $results['recordsFiltered'] ?: count($results);
$list = $results['results'] ? $results['results'] : $results;
return [
'results' => $list,
'recordsFiltered' => $total,
];
}
/**
@ -55,11 +67,12 @@ class AJAX
* @param array $where
* @param array $filter
* @param array $search
* @param array $limit
* @param array $custom
*
* @return array
*/
public static function completeResults($query, $where, $filter = [], $search = [], $custom = [])
public static function selectResults($query, $where, $filter = [], $search = [], $limit = [], $custom = [])
{
if (str_contains($query, '|filter|')) {
$query = str_replace('|filter|', !empty($filter) ? 'WHERE '.implode(' OR ', $filter) : '', $query);
@ -72,21 +85,25 @@ class AJAX
}
$query = str_replace('|where|', !empty($where) ? 'WHERE '.implode(' AND ', $where) : '', $query);
$query .= ' LIMIT '.$limit['offset'].', '.$limit['length'];
$database = database();
$rs = $database->fetchArray($query);
$data = \Util\Query::executeAndCount($query);
$rows = $data['results'];
$results = [];
foreach ($rs as $r) {
foreach ($rows as $row) {
$result = [];
foreach ($custom as $key => $value) {
$result[$key] = $r[$value];
$result[$key] = $row[$value];
}
$results[] = $result;
}
return $results;
return [
'results' => $results,
'recordsFiltered' => $data['count'],
];
}
/**
@ -196,11 +213,12 @@ class AJAX
* @param string $file
* @param string $resource
* @param array $elements
* @param array $limit
* @param mixed $search
*
* @return array|null
*/
protected static function getSelectResults($file, $resource, $elements = [], $search = null)
protected static function getSelectResults($file, $resource, $elements = [], $limit = [], $search = null)
{
$superselect = self::getSelectInfo();
@ -219,7 +237,7 @@ class AJAX
require $file;
if (!isset($results) && !empty($query)) {
$results = self::completeResults($query, $where, $filter, $search_fields, $custom);
$results = self::selectResults($query, $where, $filter, $search_fields, $limit, $custom);
}
return isset($results) ? $results : null;

View File

@ -98,8 +98,8 @@ class SelectHandler implements HandlerInterface
* Gestione dell'input di tipo "select" con richieste AJAX (nome della richiesta indicato tramite attributo "ajax-source").
* Esempio: {[ "type": "select", "label": "Select di test", "name": "test", "ajax-source": "test" ]}.
*
* @param array $values
* @param array $extras
* @param string $op
* @param array $elements
*
* @return string
*/
@ -111,10 +111,11 @@ class SelectHandler implements HandlerInterface
include DOCROOT.'/ajax_select.php';
$text = ob_get_clean();
$result = '';
$html = '';
$array = (array) json_decode($text, true);
foreach ($array as $element) {
$response = (array) json_decode($text, true);
$results = $response['results'];
foreach ($results as $element) {
$element = (array) $element;
if (isset($element['children'][0])) {
$element = (array) $element['children'][0];
@ -137,11 +138,11 @@ class SelectHandler implements HandlerInterface
}
}
$result .= '
$html .= '
<option value="'.prepareToField($element['id']).'" '.implode(' ', $attributes).'>'.$element['text'].'</option>';
}
return $result;
return $html;
}
/**

View File

@ -181,6 +181,23 @@ class Query
return $query;
}
public static function executeAndCount($query)
{
$database = database();
// Esecuzione della query
$query = self::str_replace_once('SELECT', 'SELECT SQL_CALC_FOUND_ROWS', $query);
$results = $database->fetchArray($query);
// Conteggio dei record filtrati
$count = $database->fetchOne('SELECT FOUND_ROWS() AS count');
return [
'results' => $results,
'count' => $count['count'],
];
}
/**
* Restituisce le somme richieste dalla query prevista dalla struttura.
*
@ -202,7 +219,7 @@ class Query
$result_query = self::getQuery($structure, $search);
$query = str_replace_once('SELECT', 'SELECT '.implode(', ', $total['summable']).' FROM(SELECT ', $result_query).') AS `z`';
$query = self::str_replace_once('SELECT', 'SELECT '.implode(', ', $total['summable']).' FROM(SELECT ', $result_query).') AS `z`';
$sums = database()->fetchOne($query);
$results = [];
@ -217,6 +234,28 @@ class Query
return $results;
}
/**
* Sostituisce la prima occorenza di una determinata stringa.
*
* @param string $str_pattern
* @param string $str_replacement
* @param string $string
*
* @since 2.3
*
* @return string
*/
protected static function str_replace_once($str_pattern, $str_replacement, $string)
{
if (strpos($string, $str_pattern) !== false) {
$occurrence = strpos($string, $str_pattern);
return substr_replace($string, $str_replacement, strpos($string, $str_pattern), strlen($str_pattern));
}
return $string;
}
/**
* Interpreta lo standard modulare per l'individuazione delle query di un modulo/plugin del progetto.
*